What is HAR File?
HAR (HTTP Archive) is a JSON format for recording browser HTTP transactions. Created by exporting from Browser DevTools Network tab.
How to Create HAR File
Chrome/Edge:
1. F12 → Network tab
2. Reload page or perform action
3. Right-click any request
4. "Save all as HAR with content"
Firefox:
1. F12 → Network tab
2. Click gear icon → "Save All As HAR"
HAR File Structure Overview
{
"log": {
"version": "1.2",
"creator": { ... },
"browser": { ... },
"pages": [ ... ],
"entries": [ ... ]
}
}
Complete HAR Structure
Root Object
{
"log": {
"version": "1.2",
"creator": {
"name": "WebInspector",
"version": "537.36",
"comment": ""
},
"browser": {
"name": "Chrome",
"version": "142.0.0.0",
"comment": ""
},
"pages": [
{
"startedDateTime": "2025-11-28T10:30:45.123Z",
"id": "page_1",
"title": "Example Page",
"pageTimings": {
"onContentLoad": 1234.5,
"onLoad": 2345.6
}
}
],
"entries": [
{
"pageref": "page_1",
"startedDateTime": "2025-11-28T10:30:45.123Z",
"time": 308.5,
"request": { ... },
"response": { ... },
"cache": { ... },
"timings": { ... },
"serverIPAddress": "192.168.1.100",
"connection": "443",
"_initiator": { ... },
"_priority": "High",
"_resourceType": "fetch"
}
]
}
}
log Object
Top-level container for all HAR data.
"log": {
"version": "1.2", // HAR format version
"creator": { ... }, // Tool that created HAR
"browser": { ... }, // Browser info
"pages": [ ... ], // Page load events
"entries": [ ... ], // HTTP transactions
"comment": "" // Optional comment
}
creator Object
Information about tool that generated HAR.
"creator": {
"name": "WebInspector", // Tool name
"version": "537.36", // Tool version
"comment": "" // Optional comment
}
browser Object
Browser information.
"browser": {
"name": "Chrome", // Browser name
"version": "142.0.0.0", // Browser version
"comment": "" // Optional comment
}
pages Array
Page load events (optional, may be empty).
"pages": [
{
"startedDateTime": "2025-11-28T10:30:45.123Z", // When page load started
"id": "page_1", // Unique page ID
"title": "Example Page", // Page title
"pageTimings": {
"onContentLoad": 1234.5, // DOMContentLoaded event (ms)
"onLoad": 2345.6, // window.onload event (ms)
"comment": ""
},
"comment": ""
}
]
entries Array
Array of HTTP transactions (the main data).
Each entry represents one HTTP request/response.
Entry Object Structure
Complete Entry Example
{
"pageref": "page_1",
"startedDateTime": "2025-11-28T10:30:45.123Z",
"time": 308.5,
"request": {
"method": "GET",
"url": "https://api.example.com/data",
"httpVersion": "http/2.0",
"cookies": [],
"headers": [
{"name": "accept", "value": "*/*"},
{"name": "authorization", "value": "Bearer token123"}
],
"queryString": [
{"name": "id", "value": "123"}
],
"postData": {
"mimeType": "application/json",
"text": "{\"key\":\"value\"}"
},
"headersSize": 456,
"bodySize": 18,
"comment": ""
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "http/2.0",
"cookies": [],
"headers": [
{"name": "content-type", "value": "application/json"},
{"name": "content-length", "value": "1024"}
],
"content": {
"size": 1024,
"compression": 0,
"mimeType": "application/json",
"text": "{\"data\":\"value\"}",
"encoding": "base64",
"comment": ""
},
"redirectURL": "",
"headersSize": 256,
"bodySize": 1024,
"_transferSize": 1280,
"_error": null,
"comment": ""
},
"cache": {
"beforeRequest": null,
"afterRequest": null,
"comment": ""
},
"timings": {
"blocked": 2.5,
"dns": 10.2,
"connect": 50.3,
"ssl": 80.1,
"send": 0.5,
"wait": 150.7,
"receive": 5.2,
"_blocked_queueing": 1.8,
"comment": ""
},
"serverIPAddress": "192.168.1.100",
"connection": "443",
"_initiator": {
"type": "script",
"stack": {
"callFrames": [
{
"functionName": "fetchData",
"scriptId": "123",
"url": "https://example.com/app.js",
"lineNumber": 42,
"columnNumber": 10
}
]
}
},
"_priority": "High",
"_resourceType": "fetch",
"comment": ""
}
request Object Fields
"request": {
"method": "GET", // HTTP method
"url": "https://...", // Full URL
"httpVersion": "http/2.0", // HTTP version
"cookies": [], // Request cookies
"headers": [], // Request headers
"queryString": [], // URL parameters
"postData": {}, // POST body (if applicable)
"headersSize": 456, // Headers size in bytes
"bodySize": 0, // Body size in bytes
"comment": ""
}
cookies Array
"cookies": [
{
"name": "session_id",
"value": "abc123",
"path": "/",
"domain": ".example.com",
"expires": "2025-12-31T23:59:59Z",
"httpOnly": true,
"secure": true,
"sameSite": "Lax",
"comment": ""
}
]
headers Array
"headers": [
{
"name": "content-type",
"value": "application/json",
"comment": ""
}
]
queryString Array
"queryString": [
{
"name": "id",
"value": "123",
"comment": ""
}
]
postData Object
"postData": {
"mimeType": "application/json",
"params": [], // Form parameters (if form data)
"text": "{\"key\":\"value\"}", // Request body
"comment": ""
}
response Object Fields
"response": {
"status": 200, // HTTP status code
"statusText": "OK", // Status message
"httpVersion": "http/2.0", // HTTP version
"cookies": [], // Response cookies
"headers": [], // Response headers
"content": {}, // Response body
"redirectURL": "", // Redirect location (if 3xx)
"headersSize": 256, // Headers size in bytes
"bodySize": 1024, // Body size in bytes
"_transferSize": 1280, // Total transfer size
"_error": null, // Error message (Chrome)
"comment": ""
}
content Object
"content": {
"size": 1024, // Uncompressed size
"compression": 512, // Bytes saved by compression
"mimeType": "application/json", // Content type
"text": "{\"data\":\"value\"}", // Response body
"encoding": "base64", // Encoding (if binary)
"comment": ""
}
cache Object
"cache": {
"beforeRequest": {
"expires": "2025-12-31T23:59:59Z",
"lastAccess": "2025-11-28T10:30:45.123Z",
"eTag": "abc123",
"hitCount": 5,
"comment": ""
},
"afterRequest": {
"expires": "2025-12-31T23:59:59Z",
"lastAccess": "2025-11-28T10:30:45.123Z",
"eTag": "abc123",
"hitCount": 6,
"comment": ""
},
"comment": ""
}
timings Object
"timings": {
"blocked": 2.5, // Queue time (ms)
"dns": 10.2, // DNS lookup (ms)
"connect": 50.3, // TCP connect (ms)
"ssl": 80.1, // TLS handshake (ms)
"send": 0.5, // Request send (ms)
"wait": 150.7, // TTFB (ms)
"receive": 5.2, // Response download (ms)
"_blocked_queueing": 1.8, // Browser queue (ms, Chrome)
"comment": ""
}
Chrome-Specific Fields
"_initiator": {
"type": "script", // What triggered request
"stack": { // Call stack
"callFrames": [
{
"functionName": "fetchData",
"scriptId": "123",
"url": "https://example.com/app.js",
"lineNumber": 42,
"columnNumber": 10
}
]
}
}
"_priority": "High" // Request priority
"_resourceType": "fetch" // Resource type
"_error": "net::ERR_FAILED" // Error code
Important Fields Explained
1. Request Object
"request": {
"method": "GET",
"url": "https://api.example.com/data",
"httpVersion": "http/2.0",
"headers": [
{"name": "Authorization", "value": "Bearer token123"},
{"name": "User-Agent", "value": "Mozilla/5.0..."}
],
"queryString": [
{"name": "id", "value": "123"}
],
"cookies": [],
"headersSize": 456,
"bodySize": 0
}
Key fields:
- method: HTTP method (GET, POST, PUT, DELETE, OPTIONS)
- url: Full request URL
- httpVersion: HTTP/1.1, HTTP/2.0, or http/2.0
- headers: Array of request headers
- queryString: URL parameters
- bodySize: Request body size in bytes (0 for GET)
2. Response Object
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "http/2.0",
"headers": [
{"name": "content-type", "value": "application/json"},
{"name": "content-length", "value": "1024"}
],
"cookies": [],
"content": {
"size": 1024,
"mimeType": "application/json",
"text": "{\"data\":\"value\"}"
},
"redirectURL": "",
"headersSize": 256,
"bodySize": 1024,
"_transferSize": 1280,
"_error": null
}
Key fields:
- status: HTTP status code (200, 404, 500, etc.)
- statusText: Status message (“OK”, “Not Found”, etc.)
- headers: Array of response headers
- content.size: Response body size
- content.text: Actual response body (if captured)
- bodySize: Actual bytes received
- _error: Error message if request failed
3. Timings Object
"timings": {
"blocked": 2.5,
"dns": 10.2,
"connect": 50.3,
"ssl": 80.1,
"send": 0.5,
"wait": 150.7,
"receive": 5.2,
"_blocked_queueing": 1.8
}
All values in milliseconds.
blocked
Time waiting in browser queue before request starts.
Includes:
- Waiting for available connection slot
- Proxy negotiation
- Browser connection limits
Example:
blocked: 100ms
→ Request waited 100ms before starting
dns
Time to resolve domain name to IP address.
dns: 50ms
→ DNS lookup took 50ms
dns: -1
→ DNS cached or connection reused
connect
Time to establish TCP connection.
connect: 100ms
→ TCP handshake (SYN, SYN-ACK, ACK) took 100ms
connect: -1
→ Connection reused
ssl
Time for TLS/SSL handshake.
ssl: 200ms
→ TLS handshake took 200ms
ssl: -1
→ TLS session reused
send
Time to upload request to server.
send: 5ms
→ Sending request took 5ms
send: 0
→ GET request with no body (instant)
wait
Time waiting for server response (TTFB - Time To First Byte).
wait: 500ms
→ Server took 500ms to process and start responding
This is server processing time.
receive
Time to download response body.
receive: 50ms
→ Downloading response took 50ms
_blocked_queueing
Time spent in browser’s internal queue.
Part of blocked time, shows browser-level delays.
4. Connection and Server Info
"connection": "443",
"serverIPAddress": "192.168.1.100",
"startedDateTime": "2025-11-28T10:30:45.123Z",
"time": 308.5
Key fields:
- connection: Port number used
- serverIPAddress: IP address connected to
- startedDateTime: When request started (ISO 8601)
- time: Total request time (sum of all timings)
5. Special Fields (Chrome-specific)
"_initiator": {
"type": "script",
"stack": { ... }
},
"_priority": "High",
"_resourceType": "fetch",
"_error": "net::ERR_FAILED"
Key fields:
- _initiator: What triggered the request (script, parser, etc.)
- _priority: Request priority (High, Medium, Low)
- _resourceType: Type of resource (fetch, xhr, document, etc.)
- _error: Error code if request failed
Analyzing Request Success/Failure
Success Pattern:
{
"response": {
"status": 200,
"content": {
"size": 1024,
"text": "{\"data\":\"value\"}"
},
"bodySize": 1024,
"_error": null
},
"timings": {
"blocked": 5,
"send": 2,
"wait": 100,
"receive": 10
}
}
Indicators:
- ✓ status: 200
- ✓ content.size matches bodySize
- ✓ content.text has data
- ✓ _error: null
- ✓ All timing phases completed
Failure Pattern 1: Connection Refused
{
"response": {
"status": 0,
"headers": [],
"content": {"size": 0},
"bodySize": 0,
"_error": "net::ERR_CONNECTION_REFUSED"
},
"serverIPAddress": "",
"timings": {
"blocked": 5,
"dns": -1,
"connect": -1,
"send": 0,
"wait": 0,
"receive": 0
}
}
Indicators:
- ✗ status: 0 (no HTTP response)
- ✗ Empty headers
- ✗ serverIPAddress: "" (never connected)
- ✗ _error: ERR_CONNECTION_REFUSED
- ✗ Most timings are 0 or -1
Cause: Cannot connect to server (blocked, down, or wrong address).
Failure Pattern 2: CORS Violation
{
"response": {
"status": 200,
"headers": [
{"name": "content-length", "value": "24"}
// Missing: Access-Control-Allow-Origin
],
"content": {"size": 0},
"bodySize": -326,
"_error": "net::ERR_FAILED"
},
"timings": {
"blocked": 1048,
"send": 0,
"wait": 0,
"receive": 0
}
}
Indicators:
- ✓ status: 200 (HTTP succeeded)
- ✗ Missing CORS headers
- ✗ bodySize: negative number
- ✗ content.size: 0 (should match Content-Length)
- ✗ _error: ERR_FAILED
- ✗ Large blocked time, other timings 0
Cause: Browser blocked response due to CORS policy violation.
Failure Pattern 3: Timeout
{
"response": {
"status": 0,
"_error": "net::ERR_TIMED_OUT"
},
"timings": {
"blocked": 30000,
"send": 0,
"wait": 0,
"receive": 0
}
}
Indicators:
- ✗ status: 0
- ✗ _error: ERR_TIMED_OUT
- ✗ Very large blocked time (30+ seconds)
Cause: Server didn’t respond within timeout period.
Failure Pattern 4: Proxy Issue
{
"response": {
"status": 200,
"httpVersion": "HTTP/1.1",
"headers": [
{"name": "X-Cache", "value": "MISS from proxy.company.com"},
{"name": "Content-Length", "value": "24"}
],
"content": {"size": 0},
"bodySize": -326,
"_error": "net::ERR_FAILED"
},
"serverIPAddress": "",
"timings": {
"blocked": 1048,
"send": 0,
"wait": 0,
"receive": 0
}
}
Indicators:
- ✓ status: 200
- ✓ X-Cache header (proxy involved)
- ✗ HTTP/1.1 (proxy downgraded from HTTP/2)
- ✗ serverIPAddress: "" (never reached real server)
- ✗ bodySize: negative
- ✗ Large blocked time
Cause: Proxy intercepted request but failed to deliver response body.
Comparing bodySize Values
bodySize: Positive Number
"bodySize": 1024
Meaning: Received 1024 bytes of response body. ✓
bodySize: -1
"bodySize": -1
Meaning: Body size unknown (common with HTTP/2, chunked encoding). Usually OK. ✓
bodySize: Negative (not -1)
"bodySize": -326
Meaning: Expected 326 bytes but received nothing. Error! ✗
Checking Response Body
Body Received:
"content": {
"size": 24,
"mimeType": "application/json",
"text": "{\"policyGenerations\":[]}"
}
Indicators:
- ✓ size > 0
- ✓ text field exists with data
Body NOT Received:
"content": {
"size": 0,
"mimeType": "x-unknown",
"compression": 326
}
Indicators:
- ✗ size: 0
- ✗ No text field
- ✗ compression value (expected size)
HTTP Version Indicators
HTTP/2.0 or http/2.0
"httpVersion": "http/2.0"
Meaning: Direct connection to server, modern protocol.
HTTP/1.1
"httpVersion": "HTTP/1.1"
Meaning:
- Older protocol, or
- Proxy downgraded connection
Check for X-Cache header to confirm proxy.
Debugging Checklist
1. Check Status Code
status: 200 → Success
status: 0 → Connection failed
status: 403/404/500 → Server error
2. Check Error Field
_error: null → No error
_error: "net::ERR_FAILED" → Generic failure
_error: "net::ERR_CONNECTION_REFUSED" → Can't connect
_error: "net::ERR_TIMED_OUT" → Timeout
3. Check Body Size
bodySize > 0 → Body received
bodySize: -1 → Unknown (usually OK)
bodySize: negative (not -1) → Body not received
4. Check Content
content.text exists → Body captured
content.size: 0 → Body not received
5. Check Timings
All timings > 0 → Normal flow
blocked: large, others: 0 → Stuck in queue
wait: large → Slow server
6. Check Headers
Access-Control-Allow-Origin present → CORS OK
X-Cache present → Proxy involved
Content-Length matches content.size → Complete response
Technical Terms
- HAR: HTTP Archive - JSON format for HTTP transactions
- TTFB: Time To First Byte - time until first response byte received
- bodySize: Actual bytes received in response body
- content.size: Declared size of response content
- _transferSize: Total bytes transferred (headers + body + overhead)
- blocked: Time waiting before request starts
- dns: DNS resolution time
- connect: TCP connection establishment time
- ssl: TLS/SSL handshake time
- send: Request upload time
- wait: Server processing time (TTFB)
- receive: Response download time
Common Use Cases
1. Performance Analysis
Check timings:
- dns: Slow DNS? Use CDN
- connect: Slow connection? Check network
- wait: Slow server? Optimize backend
- receive: Large response? Compress data
2. Debugging Failed Requests
Check:
- _error field for error type
- status code for HTTP errors
- headers for CORS issues
- bodySize for incomplete responses
3. Proxy Detection
Look for:
- X-Cache header
- HTTP/1.1 version (downgrade)
- serverIPAddress empty
- Missing CORS headers
4. CORS Troubleshooting
Check response headers:
- Access-Control-Allow-Origin present?
- Access-Control-Allow-Headers present?
- Status 200 but _error: ERR_FAILED?
Notes
- HAR files can contain sensitive data (tokens, cookies) - handle carefully
- Large HAR files can be slow to open - filter requests before export
- bodySize: -1 is normal for HTTP/2 and chunked encoding
- Negative bodySize (not -1) indicates error
- _error field is Chrome-specific, may not exist in other browsers
- timings with -1 mean that phase was skipped (cached/reused)
- serverIPAddress empty usually means connection failed
- X-Cache header indicates proxy involvement