getty: a netty-like asynchronous network I/O layer for Go
a netty like asynchronous network I/O library based on tcp/udp/websocket; a bidirectional RPC framework based on JSON/Protobuf; a microservice framework based on zookeeper/etcd
At a glance
- What is it?
- getty gives Go programs a session-oriented TCP, UDP and WebSocket transport with a pluggable codec and per-session goroutines, but it deliberately refuses to retry a failed write, so application code has to own delivery semantics.
- Who is it for?
- Engineers who want a netty-style session, codec and event model inside a Go service, and who accept writing their own delivery retry logic, get a compact and readable transport layer here. Teams that need built-in retries, a documented rolling upgrade path, or an off-the-shelf RPC and service-discovery stack should look elsewhere, because getty exposes the transport primitives and leaves the rest to the caller.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two goroutines per session and no built-in retry
The unit of work in getty is a session, and each session occupies two goroutines. One goroutine reads from the TCP stream, the UDP packet source, or the WebSocket connection, and the other performs the logic processing and writes the response into the network write buffer. The README is explicit about the consequence of that split: if your message handling takes a considerable amount of time, you are supposed to start your own logic goroutine inside the codec's OnMessage method rather than let the session goroutine block.
What getty does not do is retry. The transmission interface reports success or failure back to the caller and leaves the outcome to the operating system underneath. The documentation gives two distinct failure situations and expects different handling for each. A disconnect is something the caller can retry against, using the outcome of getty's automatic reconnection. A full sending buffer in the operating system is something the caller retries with its own backoff until room appears. No default policy covers either case.
That is a deliberate trade rather than an omission. It gives the caller direct control over what a delivery failure means, but it also means the library hands you an unhandled error path on every write.
The three-layer stack from application code down to UDP
getty is described as a layered design with an application layer on top, a Getty core layer in the middle, and a network layer at the bottom. The application layer holds your own code, a message handler, and the codec that implements the read and write interface. The core layer carries session management, server management, client management, connection management, an event system, and options and configuration. The network layer covers TCP, UDP, WebSocket and TLS/SSL.
The core component relationships matter more than the diagram does. Session is the central component and owns the connection lifecycle. Server and Client are the endpoint implementations for the different protocols. Connection wraps the underlying network connection. EventListener is the interface your business logic implements, and Options provides configuration.
The data flow follows that split in both directions. Inbound data runs network to getty to the package handler's read method, then to the listener's OnMessage method, then into your logic. Outbound data runs the other way, from logic into WritePkg, through the package handler's write method, and back out through getty to the network. The package handler always runs first because it performs protocol-level parsing and serialization; your listener only ever sees already decoded packets.
Heartbeats are yours on TCP and UDP, and free on WebSocket
Session timeout detection is one of the areas where getty splits responsibility in a way that surprises newcomers. For TCP and UDP you must send the heartbeat package yourself, then call the session's UpdateActive method to refresh the session's activity timestamp. Inside the codec's OnCron method you can then compare that timestamp through the session's GetActive method to decide whether the session has timed out.
For WebSocket the library takes the traffic off your hands. getty sends and receives WebSocket ping and pong frames itself, inside the session's handleLoop method. Your job is reduced to checking, in OnCron, whether the session has timed out by reading GetActive.
So the cron callback is the single place where you implement liveness policy for every transport, and the amount of code it needs varies sharply by protocol. The pattern of a heartbeat you send, followed by an activity update, is the natural place to also count consecutive failures and close a session you no longer trust.
There is no install command, only a module path and an examples repository
The README does not present an installation section, so there is nothing to copy here for fetching the package. What the repository files do give you is the module identity and the toolchain requirement it declares in go.mod:
module github.com/AlexStocks/getty
go 1.25That directive pins getty to a recent Go toolchain, and the same file lists the dependencies you will inherit in your own build graph, including the WebSocket implementation and the logging and YAML packages:
require (
github.com/gorilla/websocket v1.5.3
go.uber.org/zap v1.28.0
gopkg.in/yaml.v2 v2.4.0
)For working code, the README points to a separate repository named getty-examples, and the top level of this repository holds an examples directory, a benchmark directory, a doc directory and a change_log.md file, alongside the transport and util packages that hold the implementation. The examples directory contains an echo example and a profiles directory, which suggests the practical starting point is a runnable echo server rather than a framework guide.
The Makefile exposes the developer workflow. Its help target lists the available commands, including the transport race tests and the loopback benchmarks over TCP, WebSocket and UDP:
test - Run unit tests with coverage
test-race - Run transport race tests
bench - Run the full benchmark suite (loopback TCP/WS/UDP)Before you write any production code, run the race target and the echo example. The race tests cover the two goroutine session model, which is the part most likely to contain subtle ordering problems.
Where getty is the wrong tool
The repository description mentions three ambitions for getty: an asynchronous network I/O library, a bidirectional RPC framework built on JSON or Protobuf, and a microservice framework built on Zookeeper or etcd. What the repository layout actually exposes is the first of these. The implementation lives in transport and util, the config layer leans on the multiconfig and YAML packages, and the codec is your own file. The transport layer is the part the repository layout most clearly exposes, so a team that wants an RPC or microservice stack should check the tree before assuming it ships one.
The absence of retry is the second limitation worth stating plainly. On a lossy link or under a burst load, every write can fail, and the library will report that failure exactly once. A system where a lost request means a lost order has to build that guarantee itself, on top of a framework that offers no hooks for it beyond the write result.
The third is documentation. The README covers the session model, the layers and the heartbeat contract well, but it does not explain reconnect policy, does not document rollback, and gives no guidance on upgrading a running system across releases. The top level entries list a change_log.md, so release notes exist, but the framework itself does not tell you how to roll a new version out.
Apache-2.0 terms and a release history with long gaps
The licence field on the repository says Apache-2.0, and the LICENSE file sits at the top level next to a .licenserc.yaml configuration. Apache-2.0 is permissive, and it carries an explicit patent grant and a notice requirement, which is the part an engineer should confirm with whoever owns your legal review rather than assume. The examples directory carries its own LICENSE file, which is worth noting if you plan to copy code out of the example programs into a closed source service.
On maintenance, the last push was on 2026-10-01, so the code base is being touched. The release history, though, is uneven. The most recent tag is v1.5.2, released on 2025-09-19, before v1.5.1 on 2024-07-16 and v1.5.0 on 2024-06-05. The gap between the two earlier tags is about six weeks, while the gap between v1.5.1 and v1.5.2 is more than a year. Code moves faster than tags, and if you pin a version you inherit that gap. Go modules make this a cheap problem to sidestep, since you can depend on a commit rather than a tag, but you then take on the risk of unreleased changes.
The module path and the go directive also mean a version bump of getty can force a Go toolchain change on every service in your fleet, which is the practical upgrade cost of embedding it.
Editorial conclusion
Engineers who want a netty-style session, codec and event model inside a Go service, and who accept writing their own delivery retry logic, get a compact and readable transport layer here. Teams that need built-in retries, a documented rolling upgrade path, or an off-the-shelf RPC and service-discovery stack should look elsewhere, because getty exposes the transport primitives and leaves the rest to the caller. Before adopting it, check that the codec you write can carry your message format, that your OnCron implementation handles session timeouts, and that the Apache-2.0 licence suits your distribution model.
Frequently asked questions
What is getty and what is it used for?
getty is an asynchronous network I/O library for Go that runs over TCP, UDP and WebSocket and presents a netty-like session, codec and event listener interface. It is aimed at engineers who want the netty programming model inside a Go service.
Which network protocols does getty support?
The transport layer covers TCP, UDP and WebSocket, with TLS/SSL also shown in the network layer of the architecture diagram. Heartbeat handling differs by protocol: ping and pong frames are handled by getty for WebSocket, while TCP and UDP heartbeats are sent by the application.
Does getty retry a failed write automatically?
No. The transmission interface reports the result to the caller and the library has no internal retry mechanism. The README says the upper layer decides, handling a disconnect with the outcome of getty's automatic reconnection and a full operating system send buffer with its own retry.
How do I detect a timed out session in getty?
Implement the codec's OnCron method and read the session's activity timestamp with the GetActive method to decide whether the session has timed out. For TCP and UDP you must also send the heartbeat package yourself and call UpdateActive to refresh the timestamp.
What does getty require from my own code during message handling?
Because a session runs separate reading and logic goroutines, the README states that you should start a new logic goroutine inside the codec's OnMessage method when your processing may take a considerable amount of time.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/alexstocks-getty)Was this useful?