Groups and ids
The catalog is divided into groups.platform, labelled Global, holds the limits that apply whatever a blob’s
type. Every blob type has a group of its own, keyed by its type string, holding everything about that type —
including whether an organization may create it at all.
A limit’s id is <family>.<name>. The family is platform for a global limit, and the last segment of the type
string for a type’s limit, so the limits of blobhub.compute.workflow are named workflow.*.
Groups always come in this order. An error names a limit by its id; the limits routes return each
limit inside its group.
Kinds
Every limit has a unit —
count, bytes, seconds, days, flag or modules — and applies per one thing:
a quota per holder, such as an org or a session; a ceiling per operation or run, such as a write, a query, a
node or an execution.
How a value is chosen
- Defaults first. A limit’s value is its default unless an override applies. A user, organization or blob with no overrides works on the defaults alone.
- Overrides follow ownership. An override on a user applies to every organization that user owns. An override on an organization applies to every blob in it. An override on a blob applies to that blob alone. The nearest override wins, limit by limit.
- Ownership is read on every request. Nothing is copied when a user, organization or blob is created, so an organization that changes owner follows its new owner’s overrides from its next request.
- Work is limited where it runs. A session’s limits, and the limits of every execution in it, come from the
session’s blob — not from the blob that holds the definition being run.
workflow.running_executions_per_orgcounts against the organization of the session’s blob. A schedule’s fire runs in its target session, so the target’s limits apply. See Whose rules apply. - Each limit says where it can be overridden. The catalog’s Set on column lists the levels:
user,org,blob. A blob type’senabledentitlement, for example, can be set on a user or an organization, never on a single blob. - Some limits have a most permissive value. It comes from the platform itself — a cloud service quota, or a
timeout BlobHub configures — and no override can go past it. For
scheduler.min_interval_secondsless is more permissive, so an override can only raise it. - Fixed limits are published, not configurable. A limit whose Set on is
fixedis a bound of the platform, the same for every account. It is in the catalog so that it can be seen next to everything else. - A list is replaced, not merged. An override of
workflow.code_importsis the whole list for its level and everything below it.
Holdings
A quota counts what its holder holds now. The count lives on the holder’s own record and changes in the same step as the thing it counts: a create the API refuses takes no slot, and the step that removes a thing frees its slot.- A
failedblob or revision keeps its slot. One whose creation ends in statusfailedholds its slot until it is deleted. - A blob’s first revision takes a slot too. It is counted when the blob is created, without being checked against the limit.
- Deleting a holder deletes its counts. Deleting a session, a revision, a blob or an organization needs no separate release: the counts go with the record.
- Session objects are counted by listing them.
workflow.session_objects_per_sessionis checked only when a write would create a new alias, by counting the session’s objects. Two writes that create new aliases at the same moment can take a session one past its limit.
Reading limits
Three routes return the limits in force, group by group, with each limit’s default, where its value came from, and — where the target being read is the holder — how much is held:
The organization and blob routes need
read access to their target. A user’s limits are readable by that user, and
by anyone with admin standing on them, such as a service account’s owner. A type an organization has not enabled
still appears, with its <family>.enabled entry false, so the organization can see what it would get.
When a limit is reached
A request refused by a limit answers HTTP400 with the error limit_exceeded, except where a refusal has a code
of its own: the blob-type gate’s invalid_blob_type and the fixed limits on session writes and graph queries,
below. Each of these refusals carries a limit object naming the limit:
Key off
error and limit.id. message is prose and may be reworded.
A blob type answers with its own code. Creating a blob of a type the organization has not enabled answers
400 invalid_blob_type, and the body carries limit with the type’s entitlement, such as
{"id": "orientdb.enabled", "value": false}. A type string that names no blob type answers the same code without
limit.
The fixed limits on session writes and graph queries answer with their own codes. A request past one of them
is refused with HTTP 400 and the code below, and its body carries the same limit object — for
graph_traversal_limit_exceeded, naming the cap that tripped:
Inside
logic.code, a write refused by workflow.session_objects_per_session raises LimitExceeded, carrying the
limit object; see Code Component.
Limits during a run
create_execution resolves five limits once, and the execution keeps those values until it ends:
workflow.processor_runs_per_execution, workflow.execution_seconds, workflow.code_run_seconds,
workflow.code_imports and workflow.session_objects_per_session. A change to any of them applies to executions
created afterwards.
A schedule fire that a limit refuses is recorded in the schedule’s history with the status
refused, carrying the
same limit object. A refusal does not disable the schedule: a recurring schedule stays active and keeps firing.
See Execution History.
Retention
- Age counts from the end. An execution is past retention once it ended longer ago than its limit, and a run once it fired longer ago than its limit.
- A daily sweep removes what is older. Anything past its retention is removed by the next sweep, so it can outlive its period by up to a day.
- Only finished work. A running execution, a session and a definition are never removed by retention. Deleting a session still removes everything in it at once.
- Removing an execution frees its slot. Each execution retention removes frees one slot in its session’s
workflow.executions_per_session, so a long-lived session — one a schedule fires into every minute, say — stays below its limit. nullkeeps forever. An override can set either retention tonull.
Changing a limit
No API changes a limit: the routes above only read. Values other than the defaults are set by BlobHub. To ask for a different value, write to support@blobhub.io, naming the limit’s id, the user, organization or blob it should apply to, and the value. Afixed limit cannot be changed for one account, and no
value goes past a limit’s most permissive one.
The catalog
Every limit, by group. Per is what one value applies to. Default is the value when no override applies. Most permissive is the furthest an override can go,— when the platform sets no bound. Set on lists where
an override can be set; fixed means nowhere.
Global
Workflow
Scheduler
ONNX Model
Graph
NLP Dataset
An
enabled entitlement gates creation only. An organization whose entitlement for a type is false keeps every
blob of that type it already has.
