What is Apache Thrift?
Apache Thrift is a cross-language RPC framework originally developed at Facebook in 2007 and released as open source (later donated to the Apache Software Foundation). The core idea is simple: define your services and data types once in a language-neutral Interface Definition Language (.thrift IDL), then run the Thrift compiler to generate type-safe client and server code for any of 20+ supported languages — C++, Java, Python, Go, Ruby, PHP, Erlang, Haskell, and many more.
Thrift is used in production at Facebook, Evernote, HBase, Scribe, and Apache Cassandra. It is especially well-suited for high-performance internal microservices that need to communicate across language boundaries without sacrificing speed.
Requires libthrift-dev. Ubuntu/Debian: sudo apt install libthrift-dev
Thrift IDL Example
Define your data types, exceptions, and services in a .thrift file:
namespace cpp tutorial
typedef i32 UserId
struct User {
1: required UserId id,
2: required string name,
3: optional string email,
}
exception NotFoundException {
1: string message,
}
service UserService {
User getUser(1: UserId id) throws (1: NotFoundException ex),
list<User> listUsers(),
void createUser(1: User user),
}
Then generate code for any target language:
# Generate C++ client + server stubs
thrift --gen cpp user.thrift
# Generate Python
thrift --gen py user.thrift
# Generate Java
thrift --gen java user.thrift
Transports
Transports define how bytes move between client and server.
| Transport | Description |
|---|---|
| Socket | TCP socket — synchronous, most common for production services |
| Framed | Length-prefixed frames over any transport; required for async/non-blocking servers |
| Memory | In-memory buffer, useful for unit testing and struct serialization |
| HTTP | HTTP POST transport for REST-like or firewall-friendly deployments |
| Zlib | Transparent zlib compression wrapper over another transport |
Protocols
Protocols define how data is serialized on the wire.
| Protocol | Description |
|---|---|
| Binary | Compact binary encoding — fastest, default choice for most services |
| Compact | Variable-length integer encoding — approximately 30% smaller than Binary |
| JSON | Human-readable JSON — slowest but easiest to inspect and debug |
Servers
| Server | Description |
|---|---|
| Simple | Single-threaded — handles one client at a time; good for development |
| Threaded | Spawns one thread per client connection; simple concurrency model |
| ThreadPool | Fixed worker thread pool — recommended for production workloads |
| NonBlocking | libevent-based async I/O — highest concurrency, lowest memory per connection |
Thrift vs gRPC vs Protobuf
gRPC uses HTTP/2 + Protocol Buffers (Protobuf) as its wire format. It has excellent browser support via gRPC-Web, built-in streaming, and a rich ecosystem of middleware. Thrift uses TCP directly with its own binary format. Thrift supports 20+ languages (often more than gRPC), offers multiple protocol options (Binary, Compact, JSON), and has simpler server setup without an HTTP/2 stack dependency. Protobuf alone is just a serialization library — add gRPC on top to get RPC semantics. Choose Thrift when you need maximum language coverage, multiple protocol options, or want to avoid the HTTP/2 dependency. Choose gRPC for browser support, HTTP/2 multiplexing, or tight Google Cloud integration.
Types
type
TThriftTransport = Integer; { transport handle }
TThriftProtocol = Integer; { protocol handle }
TThriftServer = Integer; { server handle }
TThriftClient = Integer; { client connection handle }
TThriftTransportType = (
ttSocket = 0, { TCP socket }
ttFramed = 1, { framed (required for non-blocking servers) }
ttMemory = 2, { in-memory buffer }
ttHTTP = 3, { HTTP POST }
ttZlib = 4 { zlib-compressed }
);
TThriftProtocolType = (
tpBinary = 0, { fastest, default }
tpCompact = 1, { ~30% smaller than Binary }
tpJSON = 2 { human-readable }
);
TThriftServerType = (
tsSimple = 0, { single-threaded }
tsThreaded = 1, { one thread per client }
tsThreadPool = 2, { fixed pool — production }
tsNonBlock = 3 { libevent async }
);
TThriftFieldType = (
tfBool = 2, tfByte = 3, tfDouble = 4,
tfI16 = 6, tfI32 = 8, tfI64 = 10,
tfString = 11, tfStruct = 12, tfMap = 13,
tfSet = 14, tfList = 15
);
API Reference
Transport
Host:Port.Protocol
Write
MsgType: 1=call, 2=reply, 3=exception, 4=oneway. SeqID: sequence number for correlating async replies.struct).FieldID must match the IDL field number (1, 2, 3 …).WriteFieldEnd closes a field; WriteFieldStop writes the stop marker after the last field in a struct.WriteDouble, WriteBool.Read
Name is the method name, MsgType identifies the message kind.FieldType = tfStop (or FieldID = 0) to detect the stop marker.ReadFieldBegin.Serialization (without RPC)
BuildProc is the name of the procedure that writes the struct fields. Returns the raw bytes as a string.Server
ProcessorID identifies the request routing callback for dispatching incoming RPC calls.Threads worker threads. Recommended for production.StopServer is called from another thread.Code Example — Client RPC Call
uses thrift;
var
Transport: TThriftTransport;
Protocol: TThriftProtocol;
MsgName: string;
MsgType, SeqID: Integer;
begin
{ Connect: socket wrapped in framing for async-compatible server }
Transport := NewSocketTransport('localhost', 9090);
Transport := NewFramedTransport(Transport);
OpenTransport(Transport);
Protocol := NewProtocol(Transport, tpBinary);
{ Send RPC call: getUser(id=42) }
WriteMessageBegin(Protocol, 'getUser', 1, 1);
WriteStructBegin(Protocol, 'getUser_args');
WriteFieldBegin(Protocol, 'id', tfI32, 1);
WriteI32(Protocol, 42);
WriteFieldEnd(Protocol);
WriteFieldStop(Protocol);
WriteStructEnd(Protocol);
WriteMessageEnd(Protocol);
{ Read response }
ReadMessageBegin(Protocol, MsgName, MsgType, SeqID);
{ ... read response fields (struct fields for the User result) ... }
ReadMessageEnd(Protocol);
FreeProtocol(Protocol);
CloseTransport(Transport);
FreeTransport(Transport);
end.
Package Info
Install
Used By
Scribe — Apache Cassandra
Types
- TThriftTransport
- TThriftProtocol
- TThriftServer
- TThriftClient
- TThriftTransportType
- TThriftProtocolType
- TThriftServerType
- TThriftFieldType
Key Functions
- NewSocketTransport
- NewFramedTransport
- NewMemoryTransport
- OpenTransport / CloseTransport
- FreeTransport
- NewProtocol / FreeProtocol
- WriteMessageBegin/End
- WriteStructBegin/End
- WriteFieldBegin/End/Stop
- WriteString / WriteI32
- WriteI64 / WriteDouble
- WriteBool
- ReadMessageBegin/End
- ReadStructBegin/End
- ReadFieldBegin/End
- ReadString / ReadI32
- ReadI64 / ReadDouble / ReadBool
- SerializeToMemory
- DeserializeFromMemory
- NewServer
- NewThreadPoolServer
- Serve / StopServer / FreeServer
- GetLastError / ThriftVersion