Skip to content
Back to Resources
Guide

Asana Data for Analysis: Getting Numbers Out That Actually Mean Something

Skopx Team
August 5, 2026
9 min read

The fastest way to get Asana data into a form you can analyze is one of four routes, ranked by effort: CSV export from any project or search view (Project menu, Export/Print, CSV), which gives you every task with its custom fields as columns; Asana's built-in Reporting tab, which builds charts on live data without any export; Google Sheets export if you are on Business or Enterprise, which is the same data but lands directly in a sheet; or the Asana API (GET /tasks?project={gid}&opt_fields=...), which is the only route that gives you a repeatable pipeline. If you just need to answer a question this afternoon, export the CSV. If you need the same answer every Monday, use the API or a connector.

The catch that surprises almost everyone: a CSV export gives you the current state of every task, not its history. You get Completed At, Due Date, Created At and whatever custom fields exist, but you do not get "when did this move from In Progress to Review", because Asana's export does not include the status-change log. Cycle time by stage, the number one thing people actually want, is not in the file. You get it from the API (task stories, which are the activity log entries) or you get it by snapshotting your projects daily and computing transitions yourself. Everything below assumes you know that up front, because it is the difference between a two-hour analysis and a two-week one.

What each export route actually contains

RouteAvailabilityHistory includedCustom fieldsRepeatable
CSV export from projectAll paid tiersNoYes, as columnsManual
CSV export from Advanced SearchPaid tiersNoYesManual
Google Sheets exportBusiness, EnterpriseNoYesManual, re-run to refresh
Reporting tab (charts/dashboards)Premium and aboveLimited, burnup and velocity onlyYes, as chart axesLive
Portfolio progressBusiness and aboveStatus snapshots over timePortfolio fields onlyLive
API /tasks + opt_fieldsAll tiers with a tokenNo, current state onlyYes, nestedYes
API /tasks/{gid}/storiesAll tiers with a tokenYes, full activity logN/AYes
Data warehouse sync (Enterprise+)Enterprise+ tierYes, event-basedYesYes

The row that matters is the second to last one. Stories are Asana's activity feed: every comment, every assignment change, every field edit, every section move, each with a created_at and a type. That is your history. It costs one API call per task, which is why nobody does it casually across ten thousand tasks and why cycle-time reporting in Asana feels harder than it should be.

The CSV route, done properly

Open the project, click the dropdown next to the project name, choose Export/Print, then CSV. You get a file where each row is a task and columns include Task ID, Created At, Completed At, Last Modified, Name, Section/Column, Assignee, Assignee Email, Start Date, Due Date, Tags, Notes, Projects, Parent Task, Blocked By, Blocking, and then one column per custom field.

Three things to fix immediately in whatever tool you load it into:

Dates come through as strings. Asana writes dates in your workspace's format, and blank due dates come through as empty strings, not nulls. Parse explicitly rather than letting a spreadsheet guess, or you will silently get US/EU day-month flips on a subset of rows.

Subtasks may not be there. A project CSV export includes subtasks only if the subtask is itself added to the project. Subtasks that live only under their parent are absent. If your team does real work in subtasks, a project-level export undercounts everything. Use Advanced Search filtered by project instead, or pull via API with subtask traversal.

Multi-select custom fields collapse into one comma-separated cell. If you built a "Blocked reason" multi-select, one task can read Waiting on client, Missing spec. Split before you count, or your top blocker will look like a category of one.

For a one-off cycle time approximation, Completed At minus Created At gets you lead time, which is genuinely useful and takes thirty seconds. It is not cycle time. Lead time includes the weeks a ticket sat in the backlog before anybody looked at it, so it flatters or damns your team depending on how your intake works, not on how fast they execute.

Getting real history out via the API

You need a personal access token from your Asana developer console, then two calls. First, list the tasks with the fields you care about in one request rather than N requests:

GET https://app.asana.com/api/1.0/tasks
  ?project=1201234567890123
  &opt_fields=name,created_at,completed_at,completed,assignee.name,
              due_on,memberships.section.name,custom_fields.name,
              custom_fields.display_value
  &limit=100

Paginate with the offset token returned in next_page. memberships.section.name is the column the task currently sits in, which the plain task object does not give you.

Then, for the subset of tasks you actually need transitions on:

GET https://app.asana.com/api/1.0/tasks/{task_gid}/stories
  ?opt_fields=created_at,type,resource_subtype,text

Filter for resource_subtype of section_changed, assigned, enum_custom_field_changed and marked_complete. The text field reads like "moved this Task from In Progress to Review", so you can parse from and to states, and the created_at gives you the timestamp. Sort by timestamp per task and you have the state machine. Difference consecutive timestamps and you have time-in-stage.

Rate limits are the constraint: roughly 1,500 requests per minute on paid plans and 150 on free, and stories calls burn one per task. For a 5,000-task backfill on a paid plan that is a few minutes of polite looping. Do it once, store the result, then run incrementally on tasks whose modified_at changed since your last run.

Metrics worth computing, and how they break

Throughput (tasks completed per week) is the safest metric because it needs only completed_at. It breaks when teams create tasks of wildly varying size, which is every team. Segment by a size custom field or by project before you trend it, or you will read a week of small tasks as a productivity win.

Cycle time needs stories. Compute from first entry into an active section to completed_at. The failure case: tasks that get moved backwards, which happens constantly on review-heavy work. Decide explicitly whether a bounce-back restarts the clock or adds to it, and write the rule down, because the two versions produce numbers that differ by 40 percent and nobody will remember which one the dashboard uses.

Work in progress is a count of tasks in active sections at a point in time. Current-state exports can only tell you WIP today. Historical WIP requires either stories replay or a daily snapshot job. Snapshotting is cheaper: dump task ID plus section plus date every night to a table, and after a month you have a WIP trend you can trust.

On-time completion rate is completed_at <= due_on. It breaks the moment somebody edits a due date, which the current-state export will never reveal. Original due date lives only in stories (due_date_changed). Without that, an "on-time" rate can be pure theatre.

Estimate accuracy requires that estimates were captured as a numeric custom field and filled in. Check the fill rate before you report anything: if 30 percent of tasks have an estimate, you are analyzing the habits of the people who fill in estimates, not the team.

A worked example: where did Q3 go?

Question: which work type consumed the most engineering time last quarter?

  1. Advanced Search: project in [Eng Board], completed between Jul 1 and Sep 30. Export CSV. You get roughly 400 rows with a "Work type" single-select field.
  2. In a sheet, add lead_days = Completed At - Created At. Pivot by Work type: sum of lead days, count, median.
  3. The count says Bugs dominate, 210 of 400. The median lead days say Platform work dominates, 19 days versus 3.
  4. Neither is time spent. Lead days include waiting. So you go to the API for the 60 Platform tasks only, pull stories, and compute in-progress days.
  5. Result: Platform median in-progress is 4 days against 19 days lead. The bottleneck was not engineering speed, it was that Platform tasks waited two weeks for a design decision.

That last step is the whole point. The export answers what happened. The stories answer why, and the difference between 19 and 4 is a staffing conversation you would have got badly wrong from the CSV alone.

When the answer is not in Asana at all

The pattern in that example repeats: the number comes from Asana, the explanation comes from somewhere else. The two-week wait on Platform tasks shows up in Asana as an absence, a task sitting still. The reason sits in a Slack thread, a design review comment, or an email to a client, and no amount of task export will surface it. This is the structural limit of BI tools pointed at project data too: they connect to databases and modelled sources, so evidence that is a sentence somebody typed in Slack is outside what they can see.

Skopx connects to Asana alongside Slack, Gmail, Linear, GitHub and your databases, so you can ask which Platform tasks stalled last quarter and get the task data and the conversation that explains it, cited, in one answer. If the same question comes up every Monday, you can describe the view you want in a sentence and get an internal console that reads live from those tools: see Internal Apps.

Share this article

Skopx Team

The Skopx engineering and product team

Related Articles

Guide

Free Data Analysis Tools: What Each One Actually Does Well

The honest short answer: for most work, four free tools cover almost everything. Google Sheets for anything under about 100,000 rows where you need collaborators. Python with panda

10 min readAug 5, 2026
Guide

Affordable Business Intelligence: What You Actually Pay For, and What You Can Skip

The honest answer to "what is an affordable business intelligence solution" is that there are three real price tiers, and most companies overshoot by one. Under $20 per user per mo

9 min readAug 5, 2026
Guide

HR People Analytics Software: What It Does, What to Buy, and Where It Breaks

HR people analytics software connects to your HRIS, ATS, payroll, and engagement survey tools, keeps a dated history of every employee record, and turns that into headcount, attrit

9 min readAug 5, 2026
Guide

Insurance Business Intelligence Software: What It Is and How to Choose

Insurance business intelligence software is reporting and analytics tooling that reads from your policy administration, claims, billing and agency management systems and turns thos

9 min readAug 5, 2026
Guide

How AI Is Changing Data Analytics

AI is changing data analytics in five concrete ways: it has replaced the SQL-writing step with plain-English questions, it has moved the bottleneck from producing charts to trustin

8 min readAug 5, 2026
Guide

How to View Slack Analytics

Open the analytics dashboard at https://my.slack.com/admin/stats, or click your workspace name in the top left of the Slack app, then Tools & settings, then Analytics. On Enterpris

8 min readAug 5, 2026

Stay Updated

Get the latest insights on AI-powered code intelligence delivered to your inbox.