The ctx rasterizer/renderer is compact and strives towards a minimal memory footprint when used on microcontrollers. For the SDL2 and KMS/fbdev backends ctx creates multiple renderer threads, each with a separate rasterizer by default half the number of available cores - but this can be overriden with the environment variable CTX_THREADS. There is nothing shared between the rasterizers, they have their own gradient and shape-cache (explained below) and do fully independent read-only, lock-free rasterization from a shared drawlist and textures.
The rendering target is split into a grid of 8x8 cells and hashes of the rendering commands affecting each cell are accumulated. Only cells that have changed from the preceding frame are queued for rendering in threads. This way most contents can remain unchanged when all that is happening is editing of text in a terminal shell or editor. This type of caching is similar to how react uses a virtual DOM, clients do a full rerender and the system figures out bits to avoid rerendering. A longer writeup of the same idea can be found at cached software rendering page describing a similar implementation in the lite text editor.
The caching scheme used by ctx dictates that textures are valid for reuse in the current frame and if the texture was used in the previous frame. The client and the clients implement this policy separately.
When providing a NULL eid, to define_texture, the sha1 of the pixeldata is computed. If the eid was already registered and valid, we stop here and issue a ctx_texture call instead - thus client code that knows eids can always use define_texture without overhead, as well as create unique strings for new frames for video/animations.