Why it matters

Coprocessors solve real problems that would otherwise require moving data across the network. A server-side aggregation over a hundred million rows returns a single number without transferring anything to the client. A secondary index kept in sync via observer coprocessor gives near-instant lookup by non-key attributes.

The risk is that coprocessor bugs — memory leaks, infinite loops, OOMs — take down the RegionServer they run on and all the regions it hosts. Deploying coprocessors is a serious operational decision.

Advertisement

The architecture

Observer coprocessors implement callbacks for RPC events. The RegionObserver interface, for example, has methods like preGet, postGet, prePut, postPut, preScan, and postScan. When a client issues an operation, the RegionServer invokes each registered observer's pre-callback before executing the operation, then invokes each post-callback after. Observers can modify request or response objects, add audit logging, or maintain external state.

Endpoint coprocessors expose custom RPCs. A client asks the RegionServer to run a specific coprocessor endpoint with specific arguments, and the endpoint runs server-side to produce a result. This is how server-side aggregation works: the client sends 'sum this column across these rows,' the endpoint scans locally and returns the sum.

Coprocessors — run user code inside the RegionServerObserver coprocessorhooks pre/post RPC eventsEndpoint coprocessorcustom server-side RPCsRuns in the RegionServer JVM — bugs can crash the RegionServer and take down regions
Observer (hooks events) and Endpoint (custom RPCs) — both run in RegionServer JVM.
Advertisement

How it works end to end

Registration happens two ways. Global coprocessors are registered in hbase-site.xml and load on every RegionServer at startup. Table-level coprocessors are attached to specific tables via table attributes; they only load when regions for that table are hosted on the RegionServer.

On event, the RegionServer walks the list of registered coprocessors and calls each observer method in order. The user code can decide to skip subsequent observers, bypass the default handling, or continue normally.

Common patterns include: access control (block a put if the user lacks permission), triggers (write to a secondary table after a put), aggregation endpoints (server-side count/sum/avg), and cell-level transformations (compress or encrypt values on write, decompress on read).