> ## Documentation Index
> Fetch the complete documentation index at: https://tokenterminal.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Senders

> Every sending address behind every active-user count.

Two tables sit behind every active-user count in the asset tables.

`facts.asset_token_senders` records one row for each day, each deployment and each address that sent it. There is no number on the row: the row itself is the fact that this address sent this token that day. Every active-user count in the [daily asset tables](/docs/catalog/assets/metrics) is worked out from this set.

`facts.asset_token_senders_hll` holds a compact summary of the same addresses, one summary per day per deployment. It uses the same key columns, so the two tables line up row for row.

## Why counting addresses is different

Most numbers can be added up. Counts of distinct addresses cannot.

Say 100 addresses sent USDC on Monday and 100 sent it on Tuesday. The number of addresses that sent USDC over those two days is not 200. Anyone who sent on both days has been counted twice, and the two counts do not tell you how many that was. The same problem turns up across chains, across deployments and across assets. So the daily `user_*` columns in the [daily asset tables](/docs/catalog/assets/metrics) are right for the day they describe, and no use at all as ingredients for a wider figure.

That is what the second table is for. A **sketch** is a small summary of a set of addresses: a few kilobytes, however large the set. It has the one property a count lacks: two sketches can be combined into a single sketch before anything is counted. Combine the sketches for a stretch of days, a group of chains or a basket of assets, and you have one sketch covering all those addresses, with the repeats already collapsed. Count that, and every address counts once.

What you give up is exactness. A count taken off a sketch is a very good estimate rather than an exact number. The technique is called HyperLogLog++, which is where the `_hll` in the table name comes from, and ours are built at precision 15, close enough that their counts agree with the `user_*` figures published in the daily tables.

## Tables

<Tabs>
  <Tab title="Senders">
    `facts.asset_token_senders` records one row per `(timestamp, asset_token_id, sender_address)`. This table answers the questions a count cannot: how far two assets' users overlap, or whether the addresses that showed up in March are still active in June. Those need the addresses themselves, not a total.

    <table>
      <thead>
        <tr>
          <th width="220">Column</th>
          <th width="130">Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><code>timestamp</code></td>
          <td><code>TIMESTAMP</code></td>
          <td>Day the address sent the deployment. The partition column.</td>
        </tr>

        <tr>
          <td><code>asset\_token\_id</code></td>
          <td><code>STRING</code></td>
          <td>Deployment the address sent, formatted <code>\{asset\_id}-\{token\_address}-\{chain\_id}</code>.</td>
        </tr>

        <tr>
          <td><code>asset\_id</code></td>
          <td><code>STRING</code></td>
          <td>Asset the deployment belongs to.</td>
        </tr>

        <tr>
          <td><code>token\_id</code></td>
          <td><code>STRING</code></td>
          <td>Key of the deployment in <code>dimensions.tokens</code>.</td>
        </tr>

        <tr>
          <td><code>chain\_id</code></td>
          <td><code>STRING</code></td>
          <td>Chain the deployment lives on.</td>
        </tr>

        <tr>
          <td><code>symbol</code></td>
          <td><code>STRING</code></td>
          <td>Ticker symbol of the asset.</td>
        </tr>

        <tr>
          <td><code>asset\_type</code></td>
          <td><code>STRING</code></td>
          <td>Classification of the asset.</td>
        </tr>

        <tr>
          <td><code>bridged\_status</code></td>
          <td><code>STRING</code></td>
          <td>Issuance classification of the deployment: <code>native</code>, <code>bridged</code> or <code>unclassified</code>.</td>
        </tr>

        <tr>
          <td><code>token\_address</code></td>
          <td><code>STRING</code></td>
          <td>Address of the token contract.</td>
        </tr>

        <tr>
          <td><code>sender\_address</code></td>
          <td><code>STRING</code></td>
          <td>Address that sent the token that day.</td>
        </tr>
      </tbody>
    </table>
  </Tab>

  <Tab title="Senders HLL">
    `facts.asset_token_senders_hll` holds one row per `(timestamp, asset_token_id)`, the sketch of that day's senders. The key columns match the address table exactly, so any filter that works there works here.

    <table>
      <thead>
        <tr>
          <th width="220">Column</th>
          <th width="130">Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><code>timestamp</code></td>
          <td><code>TIMESTAMP</code></td>
          <td>Day the sketch summarizes. The partition column.</td>
        </tr>

        <tr>
          <td><code>asset\_token\_id</code></td>
          <td><code>STRING</code></td>
          <td>Deployment the sketch summarizes, formatted <code>\{asset\_id}-\{token\_address}-\{chain\_id}</code>.</td>
        </tr>

        <tr>
          <td><code>asset\_id</code></td>
          <td><code>STRING</code></td>
          <td>Asset the deployment belongs to.</td>
        </tr>

        <tr>
          <td><code>token\_id</code></td>
          <td><code>STRING</code></td>
          <td>Key of the deployment in <code>dimensions.tokens</code>.</td>
        </tr>

        <tr>
          <td><code>chain\_id</code></td>
          <td><code>STRING</code></td>
          <td>Chain the deployment lives on.</td>
        </tr>

        <tr>
          <td><code>symbol</code></td>
          <td><code>STRING</code></td>
          <td>Ticker symbol of the asset.</td>
        </tr>

        <tr>
          <td><code>asset\_type</code></td>
          <td><code>STRING</code></td>
          <td>Classification of the asset.</td>
        </tr>

        <tr>
          <td><code>bridged\_status</code></td>
          <td><code>STRING</code></td>
          <td>Issuance classification of the deployment: <code>native</code>, <code>bridged</code> or <code>unclassified</code>.</td>
        </tr>

        <tr>
          <td><code>token\_address</code></td>
          <td><code>STRING</code></td>
          <td>Address of the token contract.</td>
        </tr>

        <tr>
          <td><code>senders\_hll</code></td>
          <td><code>BYTES</code></td>
          <td>Compact summary of the day's sending addresses, built at precision 15. Combine these with <code>hll\_count.merge</code>. The raw bytes mean nothing read directly.</td>
        </tr>
      </tbody>
    </table>
  </Tab>
</Tabs>

## Sample queries

<Tabs>
  <Tab title="One deployment, one day">
    **Count the addresses that sent USDC on Ethereum on one day.** An exact distinct count over one deployment and one day reads a single partition.

    ```sql theme={null}
    select
        count(distinct sender_address) as senders
    from `facts.asset_token_senders`
    where asset_token_id = 'usdc-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48-ethereum'
      and timestamp >= timestamp('2026-08-01')
      and timestamp < timestamp('2026-08-02')
    ```
  </Tab>

  <Tab title="Monthly active senders">
    **Count USDC's monthly active senders across every deployment.** `hll_count.merge` combines the sketches first and counts once, so an address active on three chains counts as one.

    ```sql theme={null}
    select
        hll_count.merge(senders_hll) as monthly_active_senders
    from `facts.asset_token_senders_hll`
    where asset_id = 'usdc'
      and timestamp >= timestamp('2026-07-01')
      and timestamp < timestamp('2026-08-01')
    ```
  </Tab>

  <Tab title="Weekly senders by chain">
    **Break an asset's weekly senders down by chain.** Combining within each group keeps every group's count correct.

    ```sql theme={null}
    select
        chain_id,
        hll_count.merge(senders_hll) as weekly_active_senders
    from `facts.asset_token_senders_hll`
    where asset_id = 'usdc'
      and timestamp >= timestamp('2026-08-01')
      and timestamp < timestamp('2026-08-08')
    group by chain_id
    order by weekly_active_senders desc
    ```
  </Tab>
</Tabs>

## Notes

The sketch table answers *how many*, at any level you ask it, and it is a fraction of the size. The address table answers *who*, which is what overlap and retention questions need. A count off combined sketches is an estimate, off by well under a percent at this precision. `count(distinct sender_address)` over the addresses is exact, and you pay for the extra data it reads.
