---
title: "Artifact and index limits"
description: "Look up bundle, tool listing, startup, hub and index bounds."
canonical_url: "https://docs.oz0.ai/build/plugins/limits/artifacts"
---
# Artifact and index limits

> Look up bundle, tool listing, startup, hub and index bounds.

For: tenant administrators and plugin authors.

Look up bundle, tool listing, startup, hub and index bounds.

## The bundle

A plugin is packed into one bundle, the same format the edge builds from a Git commit, and every server reads it in memory to check it.

<table>
<thead>
  <tr>
    <th>
      Limit
    </th>
    
    <th>
      Value
    </th>
    
    <th>
      lint
    </th>
    
    <th>
      pack
    </th>
    
    <th>
      hub submit
    </th>
    
    <th>
      install
    </th>
    
    <th>
      What it says, for example
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <span id="bundle-size">
        Packed size
      </span>
    </td>
    
    <td>
      67,108,864 bytes (64 MiB) packed, gzipped
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      the plugin packs to 70 MB, more than the limit of 64 MB
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="bundle-unpacked">
        Unpacked size
      </span>
    </td>
    
    <td>
      536,870,912 bytes (512 MiB) unpacked
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      the bundle unpacks to more than 512 MB
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="bundle-entries">
        Entries
      </span>
    </td>
    
    <td>
      50,000 files and folders in a bundle
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      the bundle has more than 50000 entries
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="bundle-checked">
        Files a check reads
      </span>
    </td>
    
    <td>
      4,194,304 bytes (4 MiB) a file, 67,108,864 bytes (64 MiB) of them together
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      agents/big.yaml: is 5.2 MB; a file the manifest names may have at most 4 MB, and the plugin's checks did not read it
    </td>
  </tr>
  
  <tr>
    <td>
      <code id="files-count">
        files.count
      </code>
    </td>
    
    <td>
      100,000 files and folders in the plugin's folder, outside <code>
        .git
      </code>
      
      , <code>
        .venv
      </code>
      
      , <code>
        node_modules
      </code>
      
      , <code>
        __pycache__
      </code>
      
      , <code>
        .oz0-tools
      </code>
      
      , <code>
        dist
      </code>
      
      , <code>
        .pytest_cache
      </code>
      
       and <code>
        .ruff_cache
      </code>
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      the plugin's folder holds more than 100000 files and folders (outside .git, .venv, …)
    </td>
  </tr>
</tbody>
</table>

A file over 4 MiB, or past 64 MiB of read files, is packed and installed but not read by the checks, which never read code. A file the manifest names (an agent, a schema, instructions, a skill, a flow, an eval) must be read, so one that large is an error. Packing leaves out version control, virtual environments, build output, caches, `.env` files and whatever `.gitignore` ignores.

## The measured listing

<table>
<thead>
  <tr>
    <th>
      Limit
    </th>
    
    <th>
      Value
    </th>
    
    <th>
      lint
    </th>
    
    <th>
      pack
    </th>
    
    <th>
      hub submit
    </th>
    
    <th>
      install
    </th>
    
    <th>
      What it says, for example
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <span id="tools-listing">
        <code>
          tools.listing.json
        </code>
      </span>
    </td>
    
    <td>
      4,194,304 bytes (4 MiB)
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      tools.listing.json: is 5000000 bytes, more than the limit of 4194304
    </td>
  </tr>
</tbody>
</table>

The [measured listing](https://docs.oz0.ai/build/parts/tools/snapshots#the-measured-listing) is what `plugin test` writes: each function your servers list, with its schemas. A listing that large usually means a server lists far more functions than one plugin should hold; split the plugin.

## Tool-size and start-up budgets

Two budgets in estimated tokens keep what every model request carries small ([the size budget](https://docs.oz0.ai/build/parts/tools/definitions#the-size-budget), [the start-up budget](https://docs.oz0.ai/build/parts/skills#the-start-up-budget)). A budget is yours to raise in the plugin's files, where every reviewer sees it, up to 1,000,000.

<table>
<thead>
  <tr>
    <th>
      Code
    </th>
    
    <th>
      Limit
    </th>
    
    <th>
      lint
    </th>
    
    <th>
      pack
    </th>
    
    <th>
      hub submit
    </th>
    
    <th>
      install
    </th>
    
    <th>
      What it says, for example
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code id="tools-budget">
        tools.budget
      </code>
    </td>
    
    <td>
      Per agent: its tool definitions, <code>
        limits.tool_tokens
      </code>
      
      , 8,000 unless set. Per plugin: all its own functions, <code>
        tool_tokens
      </code>
      
       in <code>
        oz0-plugin.yaml
      </code>
      
      , 16,000 unless set
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      warning
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      agent clerk: its tool definitions come to about 2,386 tokens in every model request (an estimate), more than its budget of 2,000; the biggest: …
    </td>
  </tr>
  
  <tr>
    <td>
      <code id="tools-tokens">
        tools.tokens
      </code>
    </td>
    
    <td>
      One function's definition, 1,500
    </td>
    
    <td>
      warning
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      function office.send_invoice's definition comes to about 1,620 tokens (an estimate; more than 1500)
    </td>
  </tr>
  
  <tr>
    <td>
      <code id="startup-budget">
        startup.budget
      </code>
    </td>
    
    <td>
      Per agent: the index of its skills and its tools' manuals in its start-up context, <code>
        limits.startup_tokens
      </code>
      
      , 4,000 unless set
    </td>
    
    <td>
      error
    </td>
    
    <td>
      error
    </td>
    
    <td>
      warning
    </td>
    
    <td>
      not checked
    </td>
    
    <td>
      agent clerk: the index of its 12 skills comes to about 4,410 tokens in its start-up context (an estimate), more than its budget of 4,000; the biggest: …
    </td>
  </tr>
</tbody>
</table>

At hub submit a budget is a warning: the listing carries the figures, and its page shows them.

## The listing

What you write about a plugin when you list it, and what the hub's page and search keep of it. Only `hub submit` checks these.

<table>
<thead>
  <tr>
    <th>
      Limit
    </th>
    
    <th>
      Value
    </th>
    
    <th>
      What happens past it
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <span id="listing-summary">
        Summary
      </span>
    </td>
    
    <td>
      500 characters
    </td>
    
    <td>
      <code>
        hub submit
      </code>
      
       refuses it: "--summary is 612 characters, and a listing's summary is at most 500: say in one or two sentences what the plugin does". Without <code>
        --summary
      </code>
      
       the manifest's <code>
        description
      </code>
      
       stands in, and must fit too.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="listing-tag">
        A tag
      </span>
    </td>
    
    <td>
      1 to 32 lowercase letters, digits and dashes, starting with a letter or a digit
    </td>
    
    <td>
      <code>
        hub submit
      </code>
      
       refuses it, and so does the listing file's schema.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="listing-tags">
        Tags per listing
      </span>
    </td>
    
    <td>
      The hub's <code>
        tags.yaml
      </code>
      
      , <code>
        max_per_listing
      </code>
      
      ; 8 when it sets none
    </td>
    
    <td>
      <code>
        hub submit --hub &lt;checkout>
      </code>
      
       refuses more, naming the number and where it comes from; the hub's checks refuse them on the pull request.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="listing-links">
        Links
      </span>
    </td>
    
    <td>
      <code>
        https://
      </code>
      
       links of at most 2,048 UTF-8 bytes: a homepage, issues, and a security contact, which may be <code>
        mailto:
      </code>
    </td>
    
    <td>
      <code>
        hub submit
      </code>
      
       refuses another scheme. The Repository link is computed from the verified source, never written by you.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="readme-excerpt">
        README excerpt
      </span>
    </td>
    
    <td>
      2,000 characters of the README's first section
    </td>
    
    <td>
      Cut, never refused. The hub's page shows the whole README; the excerpt is what <code>
        oz0 hub search
      </code>
      
      , the console's Install dialog and the hub's search cards show.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="listing-graph">
        The graph
      </span>
    </td>
    
    <td>
      1,000 parts and 2,000 links between them
    </td>
    
    <td>
      The graph of the plugin's parts is cut and says so; nothing is refused.
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="listing-sbom">
        SBOM in the listing
      </span>
    </td>
    
    <td>
      500 package URLs
    </td>
    
    <td>
      The listing names the first 500; the SBOM file holds them all.
    </td>
  </tr>
</tbody>
</table>

## The hub's review caps

The hub reviews a plugin past its own caps instead of refusing it: a maintainer looks at what makes it that large. They are in the hub's `hub.yaml`, so another hub may set others.

<table>
<thead>
  <tr>
    <th>
      Limit
    </th>
    
    <th>
      Value
    </th>
    
    <th>
      What happens past it
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <span id="hub-files">
        Files
      </span>
    </td>
    
    <td>
      2,000 files in a plugin
    </td>
    
    <td>
      A finding on the pull request, which a maintainer reviews
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="hub-size">
        Size
      </span>
    </td>
    
    <td>
      25 MiB of files in a plugin
    </td>
    
    <td>
      A finding on the pull request, which a maintainer reviews
    </td>
  </tr>
  
  <tr>
    <td>
      <span id="hub-file-size">
        One file
      </span>
    </td>
    
    <td>
      5 MiB in one file
    </td>
    
    <td>
      A finding on the pull request, which a maintainer reviews
    </td>
  </tr>
</tbody>
</table>

`hub submit --check` runs the hub's own checks, so it shows these findings before the pull request.

## The signed index

<table>
<thead>
  <tr>
    <th>
      Limit
    </th>
    
    <th>
      Value
    </th>
    
    <th>
      What happens past it
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <span id="index-size">
        Index size
      </span>
    </td>
    
    <td>
      33,554,432 bytes (32 MiB), the signed envelope with its payload
    </td>
    
    <td>
      A server refuses an index that large, and keeps the copy it has. <code>
        index sign
      </code>
      
       writes each version's full listing as a detail document beside the index and signs a compact entry, so tens of thousands of versions fit.
    </td>
  </tr>
</tbody>
</table>

See [Run an index of your own](https://docs.oz0.ai/build/plugins/indexes/manage#run-an-index-of-your-own).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
