PTTBBS is the open-source software powering PTT.cc, Taiwan's largest BBS, developed and maintained by National Taiwan University students and running continuously since 1995. It supports over 300,000 registered users and thousands of discussion boards, making it one of the longest-lived and most active online communities in the Chinese-speaking internet. Source: https://github.com/ptt/pttbbs
This is a structured deep dive into its architecture and multi-user design, based on a detailed forum analysis.
Key points
- Access layer: Clients connect via Telnet (port 23), SSH (port 22), or WebSocket (through a
wsproxydaemon that translates WebSocket to Telnet, sombbsdneeds no changes). - Process model: One process per connection. The parent
mbbsddaemonaccept()s a connection andfork()s a child per user. The daemon uses a classic double-fork plussetsid()to detach from the controlling terminal. - Shared memory (SysV IPC): All child processes attach to a single
SHM_tsegment (key 1228, ~4MB configurable) containing: uhash: a chained hash table mapping user IDs to uid array indices (FNV-1a hashing, ~65,536 buckets, average chain length 2–3).utmp: online user table (userinfo_t[]) tracking pid, IP, friends, message queues, pager/invisibility state, and current mode.bcache: board header cache, sorted indices, per-board post counts and last-post times.- Storage: No database. Fixed-length binary record files:
.PASSWDS: one ~400-byte packeduserec_tper user (userid, DES-hashed password, permission level, post count, P-coin balance, etc.)..BRD: 256-byteboardheader_trecords per board (name, title, up to 3 moderators, attribute flags such as anonymous, over-18, guest-post).- Per-board
.DIR: an array of 128-bytefileheader_trecords indexing articles stored as individual files. - Article file naming:
M.1120582370.A.1EA=M.+ Unix timestamp + category letter + hex sequence number (for multiple posts within the same second). Article content is plain text with headers (author, board, title, time) and a PTT signature footer including the web URL. - Concurrency control:
- Byte-range file locks (
filelocking) on individual.PASSWDSrecords. - A semaphore (key 2010) protecting shared-memory counters.
- Atomic index updates done by writing
.DIR.tmpandrename()over the original. - Inter-user interaction: Private messages go through
msgs[]queues withSIGUSR1signal notification to the receiving process; chat targets are resolved viadestuidinto the peer'suserinfo_t; friend-online status is a direct array of utmp indices. - Performance techniques:
__attribute__((packed))structs for guaranteed fixed sizes and O(1) random access; mmap/read caching of board.DIRindexes when entering a board; preloading timezone data before forking. - Simplicity: files instead of databases, processes instead of threads.
- Fixed-length records: packed structs enable O(1) random access; fixed-length records plus a hash table effectively form a high-performance key-value store.
- Shared memory for everything: user state, online lists, and board caches all live in SHM.
- Unix philosophy: one program per job —
mbbsdhandles connections,daemon/handles background tasks. - Backward compatibility: data structures have remained compatible since 1995, allowing smooth upgrades.
- Official repository: https://github.com/ptt/pttbbs
- PTT website: https://www.ptt.cc
Deployment options
1. Single-machine multi-instance (traditional): create a bbs user, build with make all install, initialize with bin/initbbs -DoIt, start shared memory with bin/shmctl init, then launch bin/mbbsd -p 23 -d. Typically supports 1,000–2,000 concurrent connections per server.
2. WebSocket proxy (modern access): Browser → Nginx (SSL termination) → wsproxy → mbbsd on localhost:23.
3. Distributed (large sites): Load balancer (HAProxy) in front of multiple mbbsd hosts on NFS-shared storage. SysV shared memory does not span machines, so it must be replaced with Redis/Memcached (or similar techniques).
Design philosophy and legacy
Compared with modern forums (HTTP/WebSocket, thread pools or async I/O, relational databases, Redis caching, microservices, bcrypt/Argon2), PTTBBS reflects the constraints of 1995 (32MB RAM, single-core CPUs, dial-up) yet proves that a plain-text interface and file-based storage can sustain a community at very large scale. It remains an excellent case study in building high-performance systems under severe resource constraints.
References: