Etherpad is an open-source text editor replacing Google Docs for real-time collaborative drafting with distinct author colors and full revision playback.
Etherpad is a self-hosted collaborative editor for real-time document drafting. Its operational transformation engine syncs keystrokes across participants with per-author highlight colors. Every revision stays accessible through an interactive playback slider that reconstructs the document character by character.
Google Workspace handles document collaboration through Google Docs, but that capability requires a heavy web application. Loading a shared document pulls down large JavaScript bundles, consumes substantial browser memory, and introduces noticeable input latency when multiple participants type simultaneously on older laptops or constrained networks. Etherpad approaches real-time writing with an emphasis on speed. Its Easysync engine exchanges compact changesets over a persistent WebSocket connection, updating screens in tens of milliseconds without cursor lag or browser tab freezes.
This performance advantage stems from architectural focus. Google Workspace bundles spreadsheets, presentation decks, cloud storage, and enterprise directory controls that drafting sessions rarely need. Etherpad discards complex page layouts and formatting tools to focus strictly on text. Contributors open a link and write immediately without creating Google accounts or passing login prompts. Running Etherpad shifts operational responsibility to your own server, eliminating SaaS subscription costs and keeping working notes on private infrastructure.
Etherpad vs Google Docs — which should I choose? Choose Google Docs for formatted reports and spreadsheets; choose Etherpad for fast meeting notes and collaborative drafting where participants need immediate access without logins.
Can anyone edit an Etherpad document without an account? Yes. Anyone with the pad link can edit immediately, though administrators can install authentication plugins or password-protect pads when needed.
Can I self-host Etherpad on my own server? Yes. Etherpad runs on Linux, macOS, and Windows via Docker or Node.js, connecting to databases like PostgreSQL or MariaDB.
Etherpad is the right choice when instant multiplayer editing and data sovereignty matter more than word-processing formatting. Its Apache-2.0 license allows unconstrained internal hosting and code customization, while active commits through September 2026 ensure ongoing maintenance. Adopt it for fast workshop notes and drafting sessions, but retain a traditional office suite if your organization requires spreadsheet modeling.
We started this exact setup from scratch in a clean Linux machine on Nov 1, 2026 and checked it through Etherpad's own API: every check passed. Recipes are re-checked regularly and removed if they stop working.
mkdir -p etherpad && cd etherpad
curl -fsSL https://open-source.store/tools/etherpad/compose.yml -o compose.ymlcat > .env <<EOF
ADMIN_PASSWORD=$(openssl rand -hex 12)
POSTGRES_PASSWORD=$(openssl rand -hex 12)
PUBLIC_URL=http://localhost:9001
EOFADMIN_PASSWORD — Password for the admin account. Generated above; keep it secret.POSTGRES_PASSWORD — Password for the bundled PostgreSQL database. Generated above; keep it secret.PUBLIC_URL — Public URL where users access Etherpad; change to your domain in production.docker compose up -dservices:
app:
image: etherpad/etherpad:3.3.12
user: "5001:0"
ports:
- "9001:9001"
environment:
NODE_ENV: production
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
AUTHENTICATION_METHOD: apikey
DB_CHARSET: utf8mb4
DB_HOST: postgres
DB_NAME: etherpad
DB_PASS: ${POSTGRES_PASSWORD}
DB_PORT: 5432
DB_TYPE: postgres
DB_USER: etherpad
DEFAULT_PAD_TEXT: "Welcome to Etherpad!\n\nThis pad text is synchronized as you type.\n"
DISABLE_IP_LOGGING: "false"
SOFFICE: "null"
TRUST_PROXY: "false"
PUBLIC_URL: ${PUBLIC_URL}
REQUIRE_AUTHENTICATION: "true"
depends_on:
postgres:
condition: service_healthy
restart: always
volumes:
- plugins:/opt/etherpad-lite/src/plugin_packages
- etherpad-var:/opt/etherpad-lite/var
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9001/health | grep -q pass || exit 1"]
interval: 5s
timeout: 5s
retries: 10
start_period: 20s
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: etherpad
POSTGRES_USER: etherpad
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
PGDATA: /var/lib/postgresql/data/pgdata
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres_data:
plugins:
etherpad-var:
Free IDE for Java, Kotlin, Go, TypeScript and Python. Built on IntelliJ Community, fully open source, 300+ plugins.
Show that Etherpad is listed as an open-source alternative. Paste into your README:
Ubuntu 24.04 · Apple container, Docker 29.1.3, Compose 2.40.3+ds1-0ubuntu1~24.04.1. Images pulled in 56 s: etherpad/etherpad:3.3.12, postgres:15-alpine.
Based on the upstream setup. Official compose. Images pinned to 3.3.12 and postgres:15-alpine; database and admin passwords moved to .env; AUTHENTICATION_METHOD: apikey and REQUIRE_AUTHENTICATION: "true" configured for HTTP basic auth; PUBLIC_URL configured for link generation; healthcheck added to app service.
app-1 | 2026-11-01T19:46:36.810324340Z [2026-11-01T19:46:36.810] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:36.810574965Z [2026-11-01T19:46:36.810] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:36.840685465Z [2026-11-01T19:46:36.840] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:36.840793007Z [2026-11-01T19:46:36.840] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.258612090Z [2026-11-01T19:46:37.258] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.258656590Z [2026-11-01T19:46:37.258] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.258867507Z [2026-11-01T19:46:37.258] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.259090757Z [2026-11-01T19:46:37.259] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.322056132Z [2026-11-01T19:46:37.321] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.322213799Z [2026-11-01T19:46:37.322] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.323233716Z [2026-11-01T19:46:37.323] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.323340507Z [2026-11-01T19:46:37.323] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.323406174Z [2026-11-01T19:46:37.323] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.323509466Z [2026-11-01T19:46:37.323] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.338689132Z [2026-11-01T19:46:37.338] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.338839757Z [2026-11-01T19:46:37.338] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.374960216Z [2026-11-01T19:46:37.374] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.375222591Z [2026-11-01T19:46:37.375] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.439393132Z [2026-11-01T19:46:37.439] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.446013132Z [2026-11-01T19:46:37.445] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.451475132Z [2026-11-01T19:46:37.451] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.451943799Z [2026-11-01T19:46:37.451] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.452733716Z [2026-11-01T19:46:37.452] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.453279424Z [2026-11-01T19:46:37.453] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.453433799Z [2026-11-01T19:46:37.453] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.453561591Z [2026-11-01T19:46:37.453] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.475157299Z [2026-11-01T19:46:37.475] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.475236841Z [2026-11-01T19:46:37.475] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.512425882Z [2026-11-01T19:46:37.511] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.512761757Z [2026-11-01T19:46:37.512] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.512858216Z [2026-11-01T19:46:37.512] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.512996257Z [2026-11-01T19:46:37.512] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.553863632Z [2026-11-01T19:46:37.553] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.554019007Z [2026-11-01T19:46:37.553] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.554152549Z [2026-11-01T19:46:37.554] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.554249799Z [2026-11-01T19:46:37.554] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.585804132Z [2026-11-01T19:46:37.584] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.585849716Z [2026-11-01T19:46:37.585] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.585854132Z [2026-11-01T19:46:37.585] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.585856799Z [2026-11-01T19:46:37.585] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.699964799Z [2026-11-01T19:46:37.699] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.700066632Z [2026-11-01T19:46:37.700] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.761602549Z [2026-11-01T19:46:37.761] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.761832424Z [2026-11-01T19:46:37.761] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.762336591Z [2026-11-01T19:46:37.761] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.762350674Z [2026-11-01T19:46:37.762] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.762354049Z [2026-11-01T19:46:37.762] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.762777841Z [2026-11-01T19:46:37.762] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.799844841Z [2026-11-01T19:46:37.799] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.800004841Z [2026-11-01T19:46:37.799] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.812928549Z [2026-11-01T19:46:37.812] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.813348132Z [2026-11-01T19:46:37.813] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.843268299Z [2026-11-01T19:46:37.843] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:37.843581466Z [2026-11-01T19:46:37.843] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.263905966Z [2026-11-01T19:46:38.263] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.264150508Z [2026-11-01T19:46:38.264] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.441822341Z [2026-11-01T19:46:38.441] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.447909049Z [2026-11-01T19:46:38.447] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.454565341Z [2026-11-01T19:46:38.454] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.454690758Z [2026-11-01T19:46:38.454] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.516217424Z [2026-11-01T19:46:38.515] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.516302799Z [2026-11-01T19:46:38.516] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.557205674Z [2026-11-01T19:46:38.556] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.557315341Z [2026-11-01T19:46:38.557] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.588996716Z [2026-11-01T19:46:38.588] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.589278841Z [2026-11-01T19:46:38.589] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.764401800Z [2026-11-01T19:46:38.764] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:38.764496466Z [2026-11-01T19:46:38.764] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.443956800Z [2026-11-01T19:46:39.443] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.450107800Z [2026-11-01T19:46:39.449] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.455306175Z [2026-11-01T19:46:39.455] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.455524300Z [2026-11-01T19:46:39.455] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.519753758Z [2026-11-01T19:46:39.519] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:39.520113508Z [2026-11-01T19:46:39.520] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:40.445963300Z [2026-11-01T19:46:40.445] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:40.453367467Z [2026-11-01T19:46:40.453] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:40.456980592Z [2026-11-01T19:46:40.456] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:40.457160175Z [2026-11-01T19:46:40.457] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:41.448711509Z [2026-11-01T19:46:41.448] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:41.455500301Z [2026-11-01T19:46:41.455] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:41.457684801Z [2026-11-01T19:46:41.457] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:41.457947301Z [2026-11-01T19:46:41.457] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:42.451803676Z [2026-11-01T19:46:42.451] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:42.456880385Z [2026-11-01T19:46:42.456] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:43.453825302Z [2026-11-01T19:46:43.453] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:43.459583968Z [2026-11-01T19:46:43.459] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:44.455666469Z [2026-11-01T19:46:44.455] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:44.461205136Z [2026-11-01T19:46:44.461] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:45.459201761Z [2026-11-01T19:46:45.458] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:45.462128594Z [2026-11-01T19:46:45.461] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:46.462319637Z [2026-11-01T19:46:46.461] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:46.463541678Z [2026-11-01T19:46:46.463] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:47.463914637Z [2026-11-01T19:46:47.463] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:47.464886179Z [2026-11-01T19:46:47.464] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:48.468011262Z [2026-11-01T19:46:48.467] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:48.468208554Z [2026-11-01T19:46:48.468] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:49.470966055Z [2026-11-01T19:46:49.470] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:49.471306971Z [2026-11-01T19:46:49.471] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:50.472825347Z [2026-11-01T19:46:50.472] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:50.473108180Z [2026-11-01T19:46:50.472] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:51.474866472Z [2026-11-01T19:46:51.474] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:51.475042972Z [2026-11-01T19:46:51.474] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:52.476790473Z [2026-11-01T19:46:52.476] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:52.477101931Z [2026-11-01T19:46:52.477] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:53.483096125Z [2026-11-01T19:46:53.482] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:53.483784667Z [2026-11-01T19:46:53.483] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:54.486546750Z [2026-11-01T19:46:54.486] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:54.486680459Z [2026-11-01T19:46:54.486] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:55.488452001Z [2026-11-01T19:46:55.488] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:55.488740667Z [2026-11-01T19:46:55.488] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:56.489669293Z [2026-11-01T19:46:56.489] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:56.489743668Z [2026-11-01T19:46:56.489] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:57.490937585Z [2026-11-01T19:46:57.490] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:57.491181918Z [2026-11-01T19:46:57.491] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:58.492735544Z [2026-11-01T19:46:58.492] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:58.492955794Z [2026-11-01T19:46:58.492] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:59.494483003Z [2026-11-01T19:46:59.494] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:46:59.494768253Z [2026-11-01T19:46:59.494] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:47:00.498172045Z [2026-11-01T19:47:00.497] [INFO] http - Failed authentication from IP ANONYMOUS app-1 | 2026-11-01T19:47:00.498211212Z [2026-11-01T19:47:00.498] [INFO] http - Failed authentication from IP ANONYMOUS