October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk8 min

One Process, One Account: Rebuilding a Long-Running IRC Network in Go

Selçuk Karayel’s Yudum.NET rebuild puts IRC, services, web clients and Lua in one Go process to unify account state, trading independent component boundaries for fewer synchronization paths.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Selçuk Karayel’s Yudum.NET rebuild puts the IRC server, account and channel services, website, browser gateway and Lua runtime in one Go binary. The goal is to make a person’s identity, messages and permissions consistent across raw IRC, browser and website clients. The trade-off is fewer separate state and synchronization paths in exchange for a larger, shared failure domain.

Why make one process responsible for identity?

The central design constraint is that a person should remain the same person regardless of how they connect. In a split design, an IRC daemon, services daemon and website can each own or cache part of a user’s state. That creates boundaries where identities, permissions or message history can drift unless the components exchange updates reliably.

As an Amazon Associate I earn from qualifying purchases.

Karayel instead describes the services as ordinary Go packages that use the IRC server’s in-memory user and channel state and the same database as the web-facing parts. The intended result is one account resolver and shared records rather than separate copies that need to be synchronized. This is the author’s account of the implementation, not an independently inspected codebase.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Design choice What it simplifies What it costs
One process with shared server state and database Services do not need a separate server-to-server protocol, and there are fewer independently maintained views of account and channel state. A fault or resource problem in the process can affect several functions at once; services cannot be scaled or deployed independently in the same way as separate components.
Separate IRC daemon, services and web components Components can have distinct deployment, scaling and failure boundaries. They need explicit interfaces and coordination, including keeping separate representations of identity and state aligned.

This comparison is architectural reasoning, not a measured comparison of deployments. Karayel names the downside plainly: “The cost is a single failure domain.” He reports using a short-lived bridge process that opens the same port with SO_REUSEPORT while a replacement binary starts, keeping the HTTP side available during deploys. That describes one deployment technique; it does not remove the broader shared-process failure boundary.

How the same account works across IRC and the web

The authentication mechanism varies by client, but the account it resolves to is shared. Karayel’s account model describes raw IRC clients authenticating through SASL PLAIN or EXTERNAL, or through NickServ; the website uses a session cookie; and the browser app receives a short-lived token. Each route is said to reach the same account resolver.

Names are normalized before being used as map or database keys. This matters because case-folding behavior can differ across browsers, Go and SQL; without a consistent normalization rule, two spellings of a name could be treated as different keys in one layer and equivalent in another.

Message delivery follows the recipient

The reported delivery rule depends on whether the recipient is connected, not on which client the sender used. A connected recipient gets a live protocol message and the stored copy is marked read. If the recipient is offline, the message is stored unread for a later visit. The repost of Karayel’s article says offline history is retained only between mutual friends.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This separates a client’s transport from the account’s message record: changing from IRC to the browser does not, by itself, create a different recipient identity. The account and message behavior described here are the author’s reported design.

One source of shared records, with layers that point inward

The project’s package structure is described as a dependency direction: handlers call content logic, content logic calls the data layer, named veri, and lower layers do not call back upward. The author describes veri as the sole owner of shared records such as accounts, settings and messages. That boundary helps prevent multiple application layers from becoming competing owners of the same data.

In a codebase of this scale, this is an organizational constraint as much as a runtime choice. Karayel reports roughly 300,000 lines of Go, excluding 265 test files, plus about 13,000 lines of sandboxed Lua. These are the author’s approximate project counts, not independently verified measurements.

Rank #2
Book Tabs for The International Residential Code IRC 2021
  • Color-Coded Tabs: Highlight the most important sections with our colored tabs for the IRC 2021
  • Easy Navigation: Our color-coded tabs have large font and are printed on both sides so you can easily navigate the IRC 2021 Code Book
  • Alignment Card Included: Our tabs are easy to install in alignment using our tabs alignment system. Each tab includes the location and page number for super easy installation
  • Repositionable Design: If you misalign the tab no problem! The tabs are repositionable but also once they are folded, stick securely so navigating the IRC 2021 is easy and efficient
  • Laminated Durable Tabs: The tabs are laminated with 3 mil film for durability and stiffness to withstand frequent use

SQLite: separate reads from the single writer

Karayel describes SQLite as a single-writer database. The initial setup used one connection for both reads and writes, with SetMaxOpenConns(1). In the author’s stress test with 32 concurrent requests, about half of the waiting time was attributed to waiting for that connection. Reads queued behind other reads as well as writes, so merely issuing read-only work did not avoid the bottleneck.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The reported redesign uses one writer connection for writes and transactions, and a separate pool of read connections opened in WAL mode with query_only(ON). The separation addresses connection queueing; it does not make SQLite a multi-writer database. The write path still needs to respect its single-writer constraint.

Per-connection page caches also affected memory. Karayel says an earlier setup with 16 connections and 32 MB of cache per connection pushed memory toward 915 MB. The reported adjustment used smaller per-connection caches and shared mmap. These figures describe the author’s configuration and experience, not a general SQLite benchmark or a guarantee about another workload.

Backpressure: do not let a slow client hold up a channel

Each IRC connection reportedly has a bounded outbound queue, configurable by connection class. When the server broadcasts, it attempts a non-blocking send into each member’s queue instead of waiting for that client to read. If the queue is full, the lagging client is disconnected with “SendQ exceeded.” Karayel summarizes the policy as: “The server never waits for a client.”

This is a deliberate choice about who absorbs overload. A slow reader does not make the broadcaster wait indefinitely, but that reader can be disconnected and must reconnect. Queue bounds therefore protect the rest of the channel at the expense of a client that cannot keep up.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep Lua hooks out of the sender’s hot path

The Lua runtime is described as not goroutine-safe, so access is guarded by one lock. Initially, hooks ran synchronously on the sending connection’s loop. A script making an outbound HTTP call could hold the lock for seconds, delaying work for users in other channels while the runtime was unavailable.

The reported fix is a bounded, ordered worker queue drained by one worker. The sender enqueues work instead of executing the script inline. If the queue is full, the message is omitted from script processing and a count is recorded; per-account bot-command rate limits further constrain abuse. The queue preserves order for work it accepts, while its bound means the system can shed script work rather than allow a slow bot to stall message handling. As Karayel puts it, “A user’s message is never delayed by a bot.”

Go in the browser: shared implementation, different constraints

The browser programs are compiled to WebAssembly with TinyGo. Karayel reports avoiding reflection-heavy packages and using the browser’s JSON.parse through syscall/js. Explicitly sized unsigned integer types address the fact that WebAssembly’s int is 32-bit. Goroutines are cooperative in this environment, so network work uses event-loop callbacks and code must yield rather than assume a goroutine behaves like a native Go thread.

The implementation also has a strict Content-Security-Policy and a UI event-delegation layer. The author’s reported browser artifact sizes are 5.8 MB for webchat, or 1.9 MB gzipped, and 1.5 MB for the site, or 0.5 MB gzipped. These are the project’s stated build sizes; the article does not provide a comparison against another browser stack.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Gateway transport and real client addresses

The repost describes HTTP long-polling as the production browser-to-gateway transport. It mentions WebSocket and WebRTC data channels as alternatives, without reporting comparative performance results. The gateway uses WEBIRC so the IRC server sees the browser client’s real IP address rather than only the gateway’s address.

Calls, voice rooms and streaming are separate media paths

The same repost describes peer-to-peer WebRTC calls, moderated voice rooms whose state is held by the server, and one-to-many streaming over WHIP/WHEP. These are reported features, but no comparative throughput, latency or capacity results are published for them.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep game rules authoritative on the server

The described game engine separates rules, drawing and bridge packages. The server validates moves and computes the view each seat is allowed to see. In a card game, an opponent’s hand is represented to a player only as a count; spectators do not receive hidden game state. The browser renders its permitted view and submits a move selected from the legal moves supplied by the server.

This arrangement makes the client responsible for presentation and input, not for deciding whether a move is valid or what private state another player may see. It applies the same shared-state principle to games: authoritative rules and access to hidden information remain on the server.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the reported deployment figures establish—and what they do not

Karayel’s September 30, 2026 article reports the figures below. They are project-specific statements by the author, not independently verified tests.

Reported item Author’s figure Qualification
Go codebase About 300,000 lines Excludes 265 test files; approximate count reported by Karayel.
Sandboxed Lua About 13,000 lines Approximate project count reported by Karayel.
Deployment host One VPS with 6 vCPUs and 12 GB RAM Reported deployment configuration.
Statically linked binary 35 MB Reported without cgo.
Webchat WASM 5.8 MB; 1.9 MB gzipped Project build sizes reported by the author.
Site WASM 1.5 MB; 0.5 MB gzipped Project build sizes reported by the author.
Resident memory About 550 MB RSS Reported project figure; workload and measurement procedure are not specified in the article.
Earlier SQLite cache setup Memory approached 915 MB Reported for 16 connections with 32 MB of cache per connection, before the described cache and mmap adjustment.
SQLite connection stress test 32 concurrent requests; roughly half of waiting time attributed to the single connection Author-reported test of the initial one-connection setup, not an independent benchmark.

The article does not publish an independent benchmark, a user count, or a completed load-test result for several thousand concurrent browser clients. The larger gateway test is described as still underway, so the deployment figures should not be read as evidence that this concurrency target has been reached.

When this architecture is—and is not—a fit

The strongest case for this approach is a system where several interfaces genuinely need the same live account, permissions and message state, and where the team can maintain clear internal ownership boundaries. Direct calls and shared records avoid a separate services protocol and the synchronization work that comes with multiple copies of state.

The counterweight is operational concentration. Separate components offer more independent deployment and scaling options, and can limit which failures spread. In one process, isolation has to be designed inside the application: database access paths, bounded client queues and deferred bot execution are examples of the boundaries Karayel describes. None of them removes the single failure domain.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The title’s “28-year-old” wording is not supported with a timeline in the article’s body. The evidence describes a rebuild of Yudum.NET and its architecture, but does not establish the network’s historical age. The system is therefore best understood as one developer’s reported design and operating experience, not proof that a single process is always preferable or that the stated scale has been independently demonstrated.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.