The evaluation key
You met the evaluation key on Concepts: generated on your machine, uploaded to the server once, it lets the worker compute on your ciphertexts without ever being able to read them. What Concepts left out is that its size is not fixed: it is a direct consequence of the pipeline you built and the parameters you chose on the previous pages. This page is about what's inside the key, which operators need which part, and what makes it large.
Where it comes from
query_client.generate_key(load_if_exists=False), the call you saw on Deploy the Pipeline in the Key generation stage. The secret key stays on your machine. The evaluation key is uploaded to the platform as one object and held by the worker for every query after that. Generation takes longer than a query does, but it happens once per deployment.What's inside
After two ciphertexts multiply, the result has to be folded back into normal ciphertext form: the step is called relinearization, and the square key is what performs it. It is a single object, the same size whatever your pipeline does, and it's included whenever ciphertexts multiply anywhere in the pipeline.
Lets the worker rotate ciphertext slots. It is not one universal key: it is built from entries (each a small key of its own) - one for every distinct offset. This is the component that grows.
No ciphertext multiplies → no square key.
No cross-slot work → no rotation key.
Bootstrap is not a third component: when present, it adds its own rotation offsets, needs the square key, and adds dense↔sparse switching keys, inside the same key material.
One entry per offset
rotate by 2, many times → 1 entry rotate by 1, 2, 3, … 1023, once → 1,023 entries
Which operators need what
HomMulSquare key: it multiplies two ciphertextsHomSumSlotsRotation key: it works across slotsHomMatMulBoth when multiplying over the n axis: square and rotation keysHomRingSwitchRing-switch key, square key, and the inner bootstrap's rotation keysHomAdd, HomReshapeNone: no key neededstage_sizes, their stage plan. It decides which offsets the operator rotates by, and therefore how many entries it asks the key to include. How stage plans work is covered on Slots, rotations & stages.What makes it big
Everything from the previous section: which key components exist at all, and how many rotation entries there are, decided by the operators you placed and, for the ones that rotate, the stage_sizes you gave them.
Every entry is a cryptographic object built over the ring you configured, so it scales with the ring dimension n, with the total modulus from full_q_list_precision, and with the key-switching setting (decomposition_type, plus num_special_primes for hybrid or bv_gadget_bits for BV). Those are set once, at context creation, on Choosing parameters.
stage_sizes = (2,) × 10 (default)~10stage_sizes = (1024,) (collapsed)~1,023: roughly 100× the rotation keyWhere the size costs you
A bigger key takes longer for generate_key() to produce on your machine.
The whole key travels to the platform in one upload. Its size is your bandwidth cost, paid at key generation.
The worker holds the full key in GPU memory for as long as it serves queries. Expect a resident footprint comparable to the uploaded size, plus working headroom: memory a large key occupies is memory your queries can't use.
n.