Skip to content
Docs

Limits and usage

Check whether your table fits before uploading it, and understand which requests count against your allowance.
On this page

Request limits

For api.nums.world · Verified . Other deployments may differ.

LimitMaximumApplies to
max_rows300,000Rows across context and query
max_features4,095Feature columns, excluding the target
max_cells60,000,000Cells in one request
max_classes64Target classes for classification
max_request_bytes1 GiBRequest size (1,073,741,824 bytes)
max_response_bytes512 MiBResponse size (536,870,912 bytes)

All limits apply together; the maximum row and feature counts cannot necessarily be used in the same request.

Check the latest values

Limits can change. Query GET /v1/limits to check the current values. No API key is required.

Read current request limitsBASH
curl --fail --silent --show-error https://api.nums.world/v1/limits

Account allowance

Your account has a daily and a monthly allowance of cells and limits on requests per minute and per hour. Use your API key with GET https://api.nums.world/v1/usage to check usage and allowances for that credential, and every successful response carries them in metadata.quota. When an allowance runs out the service answers 429 until it resets. Nothing is invoiced and there is no overage.

Asking about your own table

GET https://api.nums.world/v1/estimate tells you whether a table of your shape will be accepted. It needs no key, uploads nothing and runs the same checks as admission control, so its verdict is the one a real request would get.

TerminalBASH
curl 'https://api.nums.world/v1/estimate?n_context=300000&n_query=1000&n_features=10'
JSON
{
  "accepted": false,
  "cells": 3010000,
  "counts_against_allowance": 3010000,
  "estimated_seconds": 99.1,
  "model": "causilo-clf",
  "deadline_s": 300.0,
  "max_context_rows": 299000,
  "code": "request_too_large",
  "reason": "301,000 rows is over the 300,000 row limit."
}

Everything in the answer except the cell count, which is exact, is a prediction from a fitted model. max_context_rows is the number of context rows that fit at your column count, which is the figure a refusal would have named. When a shape is refused, reason gives the same explanation the refusal would give.

How requests are counted

A cell is one value in a table you send, counting the context and query rows together and excluding the target column. A request that names a stored context is counted for the context rows as well, because storing a context saves the upload and not the cells.

A request refused before it runs, whether by validation, a limit or a rate limit, uses no cells, and neither does one whose response is too large to return. It still counts towards the requests per minute and per hour, as every request that reaches the service does. A request that ran and then failed uses its cells; these are the 504 and the 502 described under Errors.

A request you abandon is also counted in full. Disconnecting does not reach the machine running the prediction, which finishes the work regardless, and a call that has started cannot be cancelled, which is why POST /v1/cancel answers 501. The Python client reports this case as CausiloTimeout and does not retry, since a retry would be counted again, so give it a timeout long enough to read the answer the request has already used cells for.

Sending more than one call at a time

The rate limits are not a parallelism budget. Calls beyond what the service is running at the moment are queued and answered in turn, so none is refused for being concurrent, and the time spent waiting appears as latency.

Sending calls in parallel helps when tables are small and makes little difference when they are large, because large calls wait for the same GPU in turn. Many small queries against one table are faster as a single call with more query rows than as many calls.

A large table also delays the calls queued behind it, since it holds the queue for as long as it runs. Where latency matters, keep tables small and store the context instead of sending it again.

elapsed_s in the response measures the prediction alone and excludes the time the call spent queued, so a client measuring wall-clock time will see a larger number. The difference between the two is the time spent in the queue.

Cell accounting and recovery

Cell cost: (n_context + n_query) * n_features. Feature columns exclude the target. Reusing a stored context still counts its rows; the saving is the upload.

ConditionStatusCells chargedNext action
Refused before work starts
validation_failed, request_too_large, rate_limited
422, 413, 4290 cellsFollow the error code and retryable flag
Response cannot be returned
response_too_large
4130 cellsDo not retry the same request
Work ran; answer timed out or could not be read
upstream_unavailable, timeout
502, 504Full request cellsDo not retry the same request
Required store unavailable before work
upstream_unavailable
5030 cellsRetry
You stop waiting for a started request
Client exception: CausiloTimeout
Client timeoutFull request cellsDo not retry the same request

POST /v1/cancel returns 501; a started request cannot be stopped. Requests refused before work still count towards request-rate limits.

MeasurementUnitIncludes the queue
metadata.elapsed_ssecondsNo
Client wall-clock timesecondsYes

Client wall-clock time also includes the network round trip.