Delivered

Usage-driven QuickSight cleanup

Activity logs and API inventory snapshots, joined in Athena, to find the dashboards, analyses, and datasets nobody used and archive them automatically: about 1,100 assets removed and SPICE storage cut from 2.4 TB to about 700 GB.

Context
Advertising technology
Period
2024
My role
Data Platform Lead (designer and builder)
Stack
  • AWS Athena
  • QuickSight
  • AWS Glue

Live architecture

Usage logs in, unused assets out

Pick a component to trace what it sends and receives.

QuickSight activity logs and API inventory snapshots land in Athena. Daily usage views show which dashboards, analyses, and datasets anyone actually opened. The archiver removes assets nobody uses, records each one with where its definition went, and logs any failure to its own table.

Text description of this diagram

QuickSight activity logs and API inventory snapshots land in Athena. Daily usage views show which dashboards, analyses, and datasets anyone actually opened. The archiver removes assets nobody uses, records each one with where its definition went, and logs any failure to its own table.

  • Activity logs (queried in Athena): QuickSight API activity, scraped into Athena tables. Sends to Usage views (events).
  • QuickSight API (asset inventory): Snapshots of every dashboard, analysis, dataset, schedule, and refresh. Sends to Inventory tables (snapshots).
  • Usage views (daily views per asset): Daily views per dashboard and analysis, by user, plus dataset state and size. Sends to Archiver (views).
  • Inventory tables (dashboards, datasets): The current state of every asset, ready to join against usage. Sends to Archiver (assets).
  • Archiver (unused assets): Joins inventory to usage, archives what nobody uses, and keeps going when one asset fails. Sends to archived_objects (record), archive_error_log (failures), QuickSight (remove).
  • archived_objects (name, type, location): Every archived asset with its name, type, the location of its definition, and when it was archived.
  • archive_error_log (function, error): Failures are recorded per function instead of stopping the run.
  • QuickSight (assets + SPICE): About 1,100 assets archived, and SPICE storage down from a 2.4 TB peak to about 700 GB.

Static diagram (SVG)

The problem

QuickSight had accumulated years of dashboards, analyses, and datasets. Business users didn’t know what existed or what most of it was for, and neither did anyone else with confidence. SPICE storage peaked at 2.4 TB. The bill has two parts, per-user fees and storage, and storage is the one that moves.

Cleaning that up by hand doesn’t work. You can’t tell whether a dashboard is dead by looking at it, and nobody wants to be the person who deleted the one an executive opens once a quarter. The decision needed evidence, and the evidence was in the logs.

How it works

Two inputs, both landing in Athena. The diagram above follows them through.

Usage. QuickSight activity logs are queried in Athena and rolled up into daily views: views per dashboard and per analysis by user, plus each dataset’s state, size, and import mode.

Inventory. Snapshots from the QuickSight API fill tables for the current dashboards, analyses, datasets, schedules, and refresh history.

The archiver joins inventory to usage and removes the assets nobody is using. Each archived asset is written to an archived_objects table with its name, type, the location of its definition, and when it was archived. A failure on one asset goes to an archive_error_log table with the function and the error, and the run keeps going.

Decisions

Usage over opinion. Logs answer the question the same way for every asset, without depending on anyone’s memory of what they still open.

Record before removing. The archive table is the receipt: what went, what type it was, where its definition went, and when. If someone does come looking for something, the answer is a query.

One failure doesn’t stop the run. Errors are logged with the function that hit them and the run continues, so a problem with one asset costs a row in an error table instead of the whole cleanup.

What it enabled

About 1,100 assets were archived, and SPICE storage fell from its 2.4 TB peak to about 700 GB. As far as I could tell, users didn’t notice, which is the point of archiving by usage.

It also cleared the way for a second track on what remained: generating datasets from configuration, deploying them identically to dev, test, and production, and sharing them through folders automatically instead of one by one.

Tradeoffs and lessons

Logs only show what was logged. A rarely used asset can look dead in a short window, so the usage window has to be long enough to catch quarterly readers.

Cleanup is a prerequisite, not a project. The storage drop was the visible result. The bigger one was that the BI layer became small enough to manage deliberately.