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

ArtifactPathFormat
Chat Database~/Library/Messages/chat.dbSQLite
WAL File~/Library/Messages/chat.db-walSQLite WAL
SHM File~/Library/Messages/chat.db-shmSQLite 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:

TablePurposeRow Count Typical
messageAll sent and received messagesThousands to hundreds of thousands
handleContact identifiers (phone numbers, emails)Hundreds
chatConversations (individual and group)Hundreds
attachmentFile attachment metadataThousands
chat_handle_joinMaps participants to chatsHundreds
chat_message_joinMaps messages to chatsMatches message count
message_attachment_joinMaps attachments to messagesMatches attachment count
deleted_messagesRecently deleted message GUIDsVariable

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, or RCS.
  • 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 attributedBody BLOB column using NSKeyedArchiver format rather than the plain text column. Always check both columns. The text column may be NULL on Ventura and later.
  • Deleted messages: The deleted_messages table contains GUIDs of messages deleted within the last 30 days. The actual message content is removed from the message table but the GUID reference remains. This is evidence of deliberate deletion.
  • Group chat identification: Group chats have chat.style = 43 and a GUID format of iMessage;+;chatNNNNNNN. Individual chats use style = 45 with iMessage;-;+15551234567.
  • Attachment paths: The attachment.filename column contains the full local filesystem path. The transfer_name column 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_state and ck_record_id columns track iCloud synchronization. A non-null ck_record_id indicates the message has been synced to iCloud.

Version Differences

macOS VersionNotable Changes
10.15 CatalinaFull Disk Access (TCC) required to read chat.db
11 Big Surthread_originator_guid column added for inline replies
13 Venturatext column replaced by attributedBody BLOB (NSKeyedArchiver format)
14 SonomaEnhanced spam detection columns (is_spam)
15 SequoiaRCS support added; approximately 60 columns in message table

Tool Support

ToolSupport Level
macforFull collection: messages, attachments, reactions, deleted, groups
iLEAPPParses chat.db for iOS/macOS
AXIOMFull Messages support
CellebriteFull Messages support
sqlite3 CLIManual querying with appropriate SQL

References

Previous
Preferences