Messages
Messages (iMessage / SMS)
Overview
Messages.app is Apple's built-in messaging application on macOS, handling iMessage, SMS, MMS, and (since macOS 15 Sequoia) RCS communications. All message data is stored in a single SQLite database (chat.db) per user, making it one of the most forensically valuable artifacts on a Mac. The database contains the full text of conversations, delivery and read receipts, tapback reactions, attachment metadata, group chat memberships, and recently deleted message references.
Messages.app syncs conversations across Apple devices via iCloud, meaning the local Mac database may contain messages originally sent or received on an iPhone or iPad. Messages are stored locally in decrypted form regardless of the end-to-end encryption used in transit.
File Locations
| Artifact | Path | Format |
|---|---|---|
| Chat Database | ~/Library/Messages/chat.db | SQLite |
| WAL File | ~/Library/Messages/chat.db-wal | SQLite WAL |
| SHM File | ~/Library/Messages/chat.db-shm | SQLite SHM |
| Attachments | ~/Library/Messages/Attachments/ | Binary files |
| Sandboxed Container | ~/Library/Containers/com.apple.iChat/Data/Library/Messages/ | Various |
| Archived Conversations | ~/Library/Messages/Archive/ | Various |
| Drafts | ~/Library/Messages/Drafts/ | Various |
The Attachments directory uses a two-level hexadecimal directory structure (00-ff) with UUID-named subdirectories:
~/Library/Messages/Attachments/
ab/
{UUID}/
image.jpg
Database Schema
The chat.db database contains eight primary tables:
| Table | Purpose | Row Count Typical |
|---|---|---|
message | All sent and received messages | Thousands to hundreds of thousands |
handle | Contact identifiers (phone numbers, emails) | Hundreds |
chat | Conversations (individual and group) | Hundreds |
attachment | File attachment metadata | Thousands |
chat_handle_join | Maps participants to chats | Hundreds |
chat_message_join | Maps messages to chats | Matches message count |
message_attachment_join | Maps attachments to messages | Matches attachment count |
deleted_messages | Recently deleted message GUIDs | Variable |
See Chat Database for complete table schemas and SQL queries.
Key Fields for Analysis
message.is_from_me-- Distinguishes sent (1) from received (0) messages.message.service-- Identifies the transport:iMessage,SMS,MMS, orRCS.message.associated_message_type-- Non-zero values indicate tapback reactions (2000-3005).chat.style-- Value of 43 indicates a group chat; 45 indicates an individual conversation.message.ck_sync_state-- CloudKit synchronization status; useful for determining device origin.message.thread_originator_guid-- Links inline replies to their parent message (macOS 11+).
Timestamps
All timestamps in chat.db use the Core Data epoch in nanoseconds: the number of nanoseconds since January 1, 2001 00:00:00 UTC.
Conversion formula:
Unix nanoseconds = Core Data nanoseconds + 978307200000000000
-- Convert to human-readable UTC in SQLite
SELECT datetime(date / 1000000000 + 978307200, 'unixepoch') AS date_utc
FROM message;
Key timestamp columns: message.date, message.date_read, message.date_delivered, message.date_played, attachment.created_date.
A zero value means the timestamp was not recorded (e.g., date_read = 0 means unread).
Analysis Notes
- attributedBody migration: Starting with macOS 13 Ventura, message text is stored in the
attributedBodyBLOB column using NSKeyedArchiver format rather than the plaintextcolumn. Always check both columns. Thetextcolumn may be NULL on Ventura and later. - Deleted messages: The
deleted_messagestable contains GUIDs of messages deleted within the last 30 days. The actual message content is removed from themessagetable but the GUID reference remains. This is evidence of deliberate deletion. - Group chat identification: Group chats have
chat.style = 43and a GUID format ofiMessage;+;chatNNNNNNN. Individual chats usestyle = 45withiMessage;-;+15551234567. - Attachment paths: The
attachment.filenamecolumn contains the full local filesystem path. Thetransfer_namecolumn contains the original filename as sent. Paths beginning with~use tilde expansion relative to the user's home directory. - CloudKit sync markers: The
ck_sync_stateandck_record_idcolumns track iCloud synchronization. A non-nullck_record_idindicates the message has been synced to iCloud.
Version Differences
| macOS Version | Notable Changes |
|---|---|
| 10.15 Catalina | Full Disk Access (TCC) required to read chat.db |
| 11 Big Sur | thread_originator_guid column added for inline replies |
| 13 Ventura | text column replaced by attributedBody BLOB (NSKeyedArchiver format) |
| 14 Sonoma | Enhanced spam detection columns (is_spam) |
| 15 Sequoia | RCS support added; approximately 60 columns in message table |
Tool Support
| Tool | Support Level |
|---|---|
| macfor | Full collection: messages, attachments, reactions, deleted, groups |
| iLEAPP | Parses chat.db for iOS/macOS |
| AXIOM | Full Messages support |
| Cellebrite | Full Messages support |
| sqlite3 CLI | Manual querying with appropriate SQL |