Blog / Files, specs & sharing

P6 .xer Files Explained

An .xer file is Primavera P6's native export format, and it's the most common way a P6 schedule changes hands: from contractor to owner, from scheduler to claims consultant, from one software tool to another. It's plain text, which means you can open it and see what's inside. This post covers the structure of the file, the tables that matter for scheduling, the gotchas that cause most import problems, and a checklist for when one lands in your inbox.

What an .xer file is

When you export a project from P6 in its native format, you get an .xer file. It contains the project's data as a set of database tables, written as tab-delimited text. A single .xer can hold one project or several. It can include activities, relationships, WBS, calendars, resources and assignments, activity codes, user-defined fields, and project settings, depending on what was in the project and the export options.

What it does not contain is a picture of the schedule. Layouts, filters, column choices, bar colors, and print settings live elsewhere. Two people can import the same .xer and see completely different screens. If you need someone to see exactly what you saw, send a PDF alongside it.

The file structure

Open an .xer in a text editor and you'll see lines that begin with a marker:

MarkerMeaning
ERMHDRThe first line. Header with the P6 version, export date, and some export metadata.
%TStart of a table. The table name follows.
%FField names for that table, tab-separated.
%ROne row of data, tab-separated in the same order as the %F line.
%EEnd of file.

A trimmed example of the activity table, with tabs shown as spaces and most fields omitted:

%T  TASK
%F  task_id  proj_id  wbs_id  clndr_id  task_code  task_name               task_type  status_code   target_drtn_hr_cnt  remain_drtn_hr_cnt
%R  10021    501      7730    88        A1000      Footings Area A          TT_Task    TK_Complete   40                  0
%R  10022    501      7730    88        A1010      Underslab Plumbing A     TT_Task    TK_Active     32                  16
%R  10023    501      7731    88        A1020      SOG Pour Area A          TT_Task    TK_NotStart   16                  16
%R  10024    501      7729    90        M1000      Substantial Completion   TT_FinMile TK_NotStart   0                   0

The numeric IDs (task_id, wbs_id, clndr_id) are P6's internal keys. The task_code is the activity ID people see. Tables reference each other by the internal keys, not by activity ID.

The tables that matter

A full export includes dozens of tables. For scheduling, these are the core:

TableWhat it holds
PROJECTProject-level settings, including the data date (last_recalc_date), planned start, and scheduled finish
PROJWBSThe WBS hierarchy, including the project's root node
TASKActivities: IDs, names, types, status, durations, dates, float, constraints
TASKPREDRelationships: predecessor, successor, type, and lag
CALENDARCalendars, with work weeks and exceptions encoded in a single text field
ACTVTYPE, ACTVCODE, TASKACTVActivity code types, their values, and which activities carry which values
RSRC, TASKRSRCResources and their assignments to activities
UDFTYPE, UDFVALUEUser-defined field definitions and values
SCHEDOPTIONSScheduling options, such as how out-of-sequence progress is handled

Durations are in hours

This is the one that catches everyone. P6 stores durations, lags, and float as hours: target_drtn_hr_cnt, remain_drtn_hr_cnt, lag_hr_cnt, total_float_hr_cnt. A 5-day activity on an 8-hour-a-day calendar is stored as 40. On a 10-hour calendar it's 50.

To convert back to days, you need the hours per day for the activity's calendar. If a tool assumes 8 hours everywhere and the project uses 10-hour days, every duration and float value comes in 25% long. If you see durations like 6.25 days on an import, check the calendar's hours per day first.

Relationships

Each row in TASKPRED links a pred_task_id to a task_id with a pred_type (PR_FS, PR_SS, PR_FF, or PR_SF) and a lag_hr_cnt. Relationships to activities in other projects are allowed; they'll reference a pred_proj_id different from the activity's own. If the other project isn't in the file, those links can't be rebuilt, and the activities on either side may become open ends. See relationship types for what each type means.

Activity types and status

task_type tells you whether an activity is a task-dependent activity (TT_Task), a resource-dependent activity (TT_Rsrc), a start milestone (TT_Mile), a finish milestone (TT_FinMile), a level of effort (TT_LOE), or a WBS summary (TT_WBS). status_code is TK_NotStart, TK_Active, or TK_Complete. Actual dates are in act_start_date and act_end_date.

Calendars

The CALENDAR table holds each calendar's name, type (global, project, or resource), hours per day, and a clndr_data field that encodes the work week and every exception in a compact nested format. Exceptions are stored as date serial numbers rather than readable dates. Calendars are where imports most often go quietly wrong: a missing holiday or a misread work week shifts every date without producing an error. Calendars, holidays, and weather days covers why calendars matter so much.

What's not in the file, or not always

  • Baselines. A baseline in P6 is a separate project. It travels in an .xer only if the person exporting included it, usually as its own project in the file. If you're reviewing an update against a baseline, ask for both or ask for the baseline separately.
  • Global data that wasn't used. Exports typically include only the calendars, codes, and resources the exported projects reference.
  • Layouts and filters. As above, not included.
  • Reliable calculated values. Early dates, late dates, and float are stored from the last time the schedule was calculated. If someone edited logic and exported without rescheduling, the stored dates and the logic disagree. Reschedule after import and compare.

Encoding and version issues

An .xer is text, so it has a character encoding. P6 exports have commonly used a Windows code page rather than UTF-8. Activity names with accented characters, special dashes, or symbols can come through garbled if the reading tool guesses the wrong encoding. If names look mangled, that's usually why.

The header line records the P6 version that produced the file. Newer P6 versions add fields and tables. Older tools reading a newer file usually ignore what they don't recognize. Going the other direction (a newer file into an older P6) can fail. If an import fails outright, the version mismatch is the first thing to check.

A checklist when you receive an .xer

  1. Check the header. Which P6 version, and when was it exported?
  2. Confirm the projects. How many are in the file, and is the baseline there if you need it?
  3. Check the data date. It's last_recalc_date in the PROJECT table. It should match the update period.
  4. Check calendars. Hours per day, work week, holidays. Spot-check a few activities' durations in days.
  5. Reschedule and compare. Calculate the schedule after import and compare the finish date and a few activities' float to what the sender reported. A difference means a setting, a calendar, or the stored dates don't match the logic.
  6. Count relationships and open ends. Activities with no predecessor or no successor beyond the start and finish milestones should be rare. A DCMA 14-point check covers this and more.
  7. Look at constraints. Hard constraints in the TASK table (cstr_type, cstr_date) can hold dates in place regardless of logic.
  8. Ask for a PDF of the layout the sender uses, so you know what they were looking at.

Reading one without P6

You don't need a P6 license to look inside an .xer. Any text editor will open it, and a spreadsheet can split the tab-delimited rows into columns once you separate the tables. That's enough to answer quick questions: how many activities, what calendars, what's the data date.

For anything more, you want a tool that rebuilds the network and recalculates it. schedule.construction imports .xer files directly in the browser, so you can review the network and run DCMA-style quality checks without a P6 seat. Whatever you use, verify the calculated finish against the sender's, per step 5 above. For moving schedules the other way, or between other tools, see moving schedules between P6, MS Project, and everything else.

Key takeaways

  • An .xer is tab-delimited text: %T starts a table, %F lists fields, %R is a row.
  • Durations, lags, and float are stored in hours. Convert using each calendar's hours per day.
  • Baselines and layouts don't travel unless someone deliberately includes them.
  • Stored dates reflect the last calculation, not necessarily the current logic. Reschedule after import and compare.
  • Calendars and encoding are the usual sources of quiet import errors.