# Finding what to remove

> Find cleanup candidates, large and forgotten files, duplicate copies, and apps with their leftovers. Every command here only reads.

These commands list what you could remove. None of them deletes anything: to delete what they find, use [`clean`](https://diskcensus.com/docs/cli/clean.md#clean) for the safe tier, or [`apply`](https://diskcensus.com/docs/cli/clean.md#apply) with the paths you choose.

## census findings

**Usage:** `census findings [SCOPE] [--category CATEGORY] [--safety safe|review|keep] [--limit N] [--refresh] [--progress] [--json]`

Lists the cleanup candidates census recognizes, grouped by [safety tier](https://diskcensus.com/docs/cli/safety.md#tiers): `safe` items rebuild themselves, `review` items need a person, and `keep` items are shown but never offered.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--category CATEGORY` | `developer`, `app_cache`, `logs`, `trash`, `installers`, `device_backups` or `ai_agents` |
| `--safety LEVEL` | `safe`, `review` or `keep` |
| `--limit N` | Show at most `N` per safety level (default: 10; `0` means all) |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | With `--refresh`, write scan progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
# Everything, ten per tier
census findings

# Developer caches and build output that clean would delete
census findings --category developer --safety safe --limit 0

# What AI coding agents leave behind
census findings --category ai_agents
```

The JSON totals count every match before `--limit`:

```json
{
  "schema_version": 5,
  "command": "findings",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "results": {
    "findings": [],
    "totals": {
      "safe": { "allocated_bytes": 0, "count": 0 },
      "review": { "allocated_bytes": 0, "count": 0 },
      "keep": { "allocated_bytes": 0, "count": 0 }
    },
    "truncated": 0
  }
}
```

`ai_agents` covers AI coding agents such as Claude Code, Codex and Cursor: old versions, caches, temporary files and logs, plus their history as `keep`. See [Cleaning agent data](https://diskcensus.com/docs/agents/agent-data.md).

## census large

**Usage:** `census large [--folders] [--min-size SIZE] [--not-opened DAYS] [--not-modified DAYS] [--limit N] [SCOPE] [--refresh] [--progress] [--json]`

Lists the largest files you can delete, or folders with `--folders`, largest first. A drive or data scan searches your home folder and `/Users/Shared`.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--folders` | List folders instead of files |
| `--min-size SIZE` | Minimum size on disk (default: `100M`) |
| `--not-opened DAYS` | Only items not opened in `DAYS` days. Items never opened match too. |
| `--not-modified DAYS` | Only items not modified in `DAYS` days |
| `--limit N` | Show at most `N` (default: 50; `0` means all, up to 10,000) |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | With `--refresh`, write scan progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
# Files of 1 GB or more, not opened in a year
census large --min-size 1G --not-opened 365 --json
```

```json
{
  "schema_version": 5,
  "command": "large",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "scan": { "scope_kind": "drive", "scan_id": "…" },
  "results": {
    "items": [
      {
        "path": { "display": "/Users/me/Movies/archive.mov", "lossy": false },
        "kind": "file",
        "allocated_bytes": 6810000000,
        "logical_bytes": 6790000000,
        "modified_unix_ms": 1790000000000,
        "opened_unix_ms": null,
        "selectable": true,
        "rule": null
      }
    ],
    "total": { "count": 1, "allocated_bytes": 6810000000 },
    "truncated": 0,
    "filters": {
      "folders": false,
      "min_size_bytes": 1000000000,
      "not_opened_days": 365,
      "not_modified_days": null
    },
    "places": [{ "display": "/Users/me", "lossy": false }],
    "folder_opened_dates": null
  }
}
```

- **Never listed:** macOS's own volumes, apps and everything inside them, anything inside a package (a `.photoslibrary` is one item, as Finder shows it), synced folders (iCloud Drive, `~/Library/CloudStorage`, Dropbox), the Trash, census's own folders, hard-linked files, and anything you can't delete. Protected folders such as `~/Documents` are searched, but never listed themselves.
- **Folders never nest.** A folder inside or around a listed folder isn't listed.
- **Dates:** `modified_unix_ms` is the modification time, or for a folder the newest inside it. `opened_unix_ms` is Finder's Date Last Opened, `null` when never opened.
- **Kept items** (`safety: keep`), and items inside them, have `selectable: false`.
- **`total`** counts every match before `--limit`.

Each run saves the items it returned, so [`apply`](https://diskcensus.com/docs/cli/clean.md#apply) can delete the ones you choose. Runs on the same scan add to that list; a new scan starts a new one.

## census duplicates

**Usage:** `census duplicates [SCOPE] [--under PATH] [--min-size SIZE] [--limit N] [--refresh] [--progress] [--json]`

Finds identical files and the space their extra copies take. `census dupes` is the same command. It searches files of at least 1 MB in your home folder, `/Users/Shared`, iCloud Drive and `~/Library/CloudStorage`, comparing sizes, then the first 16 KiB, then the full contents. iCloud files that aren't downloaded are skipped, never downloaded. Digests are remembered between runs, so unchanged files aren't read again.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--under PATH` | Only within this folder |
| `--min-size SIZE` | Files of at least this size: bytes, or a `K`, `M` or `G` value (default: `1M`) |
| `--limit N` | Show at most `N` groups (default: 20; `0` means all) |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | Write scan and hashing progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
# Duplicates of 1 MB or more in your home folder and iCloud Drive
census duplicates

# Only in Downloads, smaller files too, after a fresh scan
census duplicates --under ~/Downloads --min-size 500K --limit 10 --refresh
```

```sh
census duplicates --path /Applications --under /Applications/Utilities --limit 1 --json
```

```json
{
  "schema_version": 5,
  "command": "duplicates",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "results": {
    "groups": [],
    "group_count": 0,
    "min_size_bytes": 1000000,
    "reclaimable_bytes": 0,
    "roots": [{ "display": "/Applications/Utilities", "lossy": false }]
  }
}
```

Copies that are APFS clones share their storage, so deleting one frees almost nothing. Sets whose copies are all clones of one another aren't reported. Each search saves the copies it showed, so [`apply`](https://diskcensus.com/docs/cli/clean.md#apply) can delete the ones you choose. At least one copy of every set always stays.

## census apps

**Usage:** `census apps [SCOPE] [--all] [--limit N] [--refresh] [--progress] [--json]`

Lists installed apps, largest first, by the app's size plus the Library items that belong to it. Needs a scan that includes `/Applications` and `~/Library`, which the default drive scan does.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--all` | Include apps that are part of macOS |
| `--limit N` | Show at most `N` apps (default: all; `0` means all) |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | With `--refresh`, write scan progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
census apps --json
```

```json
{
  "schema_version": 5,
  "command": "apps",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "results": [
    {
      "allocated_bytes": 3891544064,
      "bundle_id": "com.apple.dt.Xcode",
      "leftover_bytes": 2834432,
      "leftover_count": 7,
      "name": "Xcode",
      "path": { "display": "/Applications/Xcode.app", "lossy": false },
      "system": false,
      "total_bytes": 3894378496,
      "version": "27.0"
    },
    "…"
  ]
}
```

A scan without your apps returns `not_found`:

```json
{
  "schema_version": 5,
  "command": "apps",
  "status": "not_found",
  "exit_code": 7,
  "errors": [
    {
      "code": "apps_not_scanned",
      "message": "This scan does not include your apps. Run \"census scan\" (the whole drive) first."
    }
  ],
  "warnings": [],
  "results": []
}
```

## census app

**Usage:** `census app NAME_OR_BUNDLE_ID [SCOPE] [--verbose] [--refresh] [--progress] [--json]`

Shows one app and the Library items that belong to it, with how sure census is (`confidence`) and whether each is shared or needs an administrator. This is what [`uninstall`](https://diskcensus.com/docs/cli/clean.md#uninstall) would remove.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--verbose` | Show the evidence for each leftover |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | With `--refresh`, write scan progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
census app xcode --json
```

```json
{
  "schema_version": 5,
  "command": "app",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "results": {
    "app": {
      "name": "Xcode",
      "bundle_id": "com.apple.dt.Xcode",
      "version": "27.0",
      "allocated_bytes": 3891544064,
      "leftover_bytes": 2834432,
      "total_bytes": 3894378496
    },
    "leftovers": [
      {
        "path": { "display": "/Users/me/Library/Caches/com.apple.dt.Xcode", "lossy": false },
        "location": "Caches",
        "confidence": "high",
        "allocated_bytes": 1499136
      },
      "…"
    ],
    "estimated_freed_bytes": 3894374400
  }
}
```

`estimated_freed_bytes` counts the app and its high-confidence, unshared items that don't need an administrator. Hard links and APFS clones can make the space actually freed differ.

## census leftovers

**Usage:** `census leftovers [SCOPE] [--verbose] [--limit N] [--refresh] [--progress] [--json]`

Lists Library items named after bundle IDs with no installed app from that developer. They are possible leftovers of apps you removed, so check them before you remove anything. If the scan couldn't read a Library folder, `not_inspected` names it: what is in it is unknown, not absent.

| Option | Description |
| --- | --- |
| `--scope KIND` | `drive` (the default) or `data` |
| `-p, --path PATH` | A folder's own scan |
| `--verbose` | Show the evidence for each leftover |
| `--limit N` | Show at most `N` apps' leftovers (default: all; `0` means all) |
| `--refresh` | Rescan first; otherwise the saved scan is read |
| `--progress` | With `--refresh`, write scan progress as NDJSON to stderr |
| `--json` | Write one JSON response |

```sh
census leftovers --json
```

```json
{
  "schema_version": 5,
  "command": "leftovers",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "results": {
    "truncated": 0,
    "groups": [],
    "not_inspected": [{ "display": "/Users/me/Library/Cookies", "lossy": false }]
  }
}
```
