Performance and scaling
On October 27, 2026, one Go server handled 10,000 authenticated WebSpace WebSocket connections and delivered all 100,000 expected events. A mixed SQLite3 test also completed 1,000 writes and 10,000 reads while keeping 10,000 connections open.
Download the validation results and measurements for each run (JSON). These tests used the dedicated WebSpace real-time route, separate from Workspace chat.
Test environment and settings
| Item | Test conditions |
|---|---|
| Date | October 27, 2026, Korea Standard Time |
| Server | Intel Core i9-14900K, 32 logical CPUs, about 62.6 GiB RAM, one Go process |
| Storage | NVMe SSD (SHPP41-2000GM), WSL2 virtual disk (ext4), Ubuntu 26.04 |
| Load generators | Four Node processes on the same machine, four loopback source IPs, one authenticated account |
| Transport | Local loopback; no WAN, TLS, or production proxy |
| SQLite3 | WAL, synchronous=NORMAL, 5-second busy timeout, up to eight read connections, one write queue per DB |
| WebSocket limits | 12,000 per server and per DB, 10,000 per IP, 10,000 messages per second per connection |
| HTTP limits | Read, mutation, and handshake: each 20,000 requests/second per IP, burst 30,000 |
A dedicated development build bypassed license tier checks. Authentication, permissions, and Origin checks ran through the normal WebSpace route. Databases were stored on disk-backed ext4, not a memory filesystem (tmpfs). The generators applied no read request pacing or limit on writes in flight.
HTTP limits were applied at startup through requestsPerSecond and burst under webspace.rateLimits.read, webspace.rateLimits.mutation, and webspace.rateLimits.handshake. These test settings differ from the defaults. Manage real-time connection limits under Services and capacity.
Connections and delivery from 5,000 to 10,000
Each connection received ten events, with three runs at each scale. Every run had zero missing, duplicate, or cross-room deliveries.
| Authenticated connections | Delivered / expected per run | All connections ready | Event delivery p95 |
|---|---|---|---|
| 5,000 | 50,000 / 50,000 | 1.25 s | 110 ms |
| 7,500 | 75,000 / 75,000 | 1.77 s | 183 ms |
| 10,000 | 100,000 / 100,000 | 2.66 s | 312 ms |
Times are medians of three runs. Connection readiness includes generator startup, the connection ramp, authentication, and subscription completion. Delivery p95 is the 95th percentile of the time from sending an event to receiving it; the table shows the median of the three run-level p95 values. The September test timed completion of all ten events per connection, so its latency figures are not directly comparable.
1,000 SQLite3 writes and 10,000 reads
With 10,000 authenticated connections open, the generators issued 1,000 state changes to a shared resource alongside 10,000 HTTP reads. Each database serialized writes through its queue.
| HTTP read concurrency setting | Runs | Successful writes | Successful reads | Mixed workload completion |
|---|---|---|---|---|
| 128 | 3 | 1,000 / 1,000 per run | 10,000 / 10,000 per run | Median 2.69 s |
| 10,000 | 1 | 1,000 / 1,000 | 10,000 / 10,000 | 3.11 s |
Completion covers the read/write phase after connection setup. A concurrency setting of 10,000 describes how clients issue requests; SQLite did not execute 10,000 queries at once. Its read pool allowed up to eight connections.
All reads returned HTTP 200, with no HTTP 429 responses or write errors. In the 10,000-request concurrency test, write p95 was 858 ms and read p95 was about 2.88 s. All four test databases had 1,000 unique actions, a resource value of 100,000→99,000, version 1,000, and 1,000 rewards. SQLite integrity_check returned ok for each database.
Active connections, rooms, and reconnection
A test with 10,000 connections sent ten events in each of twelve rounds, waiting five seconds between rounds. All 1,200,000 deliveries completed in about 67.27 seconds, with no missing or duplicate events. After 100 connections were abruptly closed and reconnected, all 10,000 follow-up events arrived.
A separate test split the connections across 100 rooms of 100 connections each. All 100,000 initial events arrived, with no cross-room delivery. Delivery after a 20-second idle period and after reconnecting 100 connections also passed. Across all 15 test cases, peak observed server RSS was about 1.50 GiB. No connections remained after the tests.
Latency and storage-path effects
During the active-connection test, periodic token revalidation across the full subscription namespace coincided with per-round delivery p95 values of about 1.91–2.31 seconds. The 312 ms figure from short delivery runs is therefore not a sustained latency guarantee.
An earlier test used the Windows shared filesystem in WSL (9p). Only 414 of 1,000 concurrent writes completed; the rest exceeded the five-second write wait/transaction budget. The successful results above used a WSL ext4 virtual disk on the same NVMe SSD. Results can vary with the storage access method.
With the default read limit of 500 requests/second per IP and a burst of 1,200, 37 reads returned HTTP 429. The final tests raised the HTTP limits instead of slowing the generators.
Choosing a configuration for your workload
| Workload | Configuration to assess |
|---|---|
| Single server, internal tools, writes that can be queued | SQLite3, tested with your actual read/write ratio |
| Sustained writes across many rooms or resources | Consider PostgreSQL or MySQL/MariaDB |
| Multiple servers and replication | Assess an external DB and event delivery between servers |
| Real-time delivery latency | Check room size, message size, fan-out, and authentication revalidation cost |
A queue orders concurrent writes; throughput remains bounded. The connection count here represents authenticated sockets from one account. The tests do not establish capacity for the complete workflows of 10,000 distinct users or a sustained long-running workload. Measure with your production TLS, proxies, WAN, and workload mix.
Use Operations to review requests, errors, response times, and DB status. For a complete user flow, try the sample in Build a real-time Gomoku game.