What Is the Size Cap for Media Transfers in BitChat?

BitChat enforces a strict limit of 256 fragments per private media transfer, with each fragment capped at 16 KiB, yielding a hard maximum payload of approximately 4 MiB.

The permissionlesstech/bitchat repository implements a Bluetooth Low Energy (BLE) messaging protocol that restricts media transfers to ensure reliable peer-to-peer delivery. This size cap for media transfers in BitChat is defined at the protocol level by the fragment planner and verified through unit testing. Understanding this ceiling is essential for developers building clients that share images, audio, or documents over the BitChat network.

How the 4 MiB Limit Is Calculated

BitChat transmits large media files by splitting them into fixed-size blocks called fragments. The total transferable size is the product of the maximum fragment count and the fixed payload size per fragment.

The 256-Fragment Hard Cap

According to bitchatTests/Services/BLEOutboundFragmentPlannerTests.swift, the BLEOutboundFragmentPlanner validates every transfer against a hard ceiling of 256 fragments. The test suite explicitly verifies that the planner accepts exactly 256 fragments and rejects 257, establishing an immutable boundary for single-transfer payloads.

Fixed 16 KiB BLE Payload Blocks

Each fragment is constrained to 16 KiB (16,384 bytes), which aligns with standard BLE transport layer specifications. Multiplying 256 fragments by 16 KiB results in a total capacity of 4 MiB (4,194,304 bytes), the definitive maximum for any private media transfer within the protocol.

Source Code Verification

The enforcement mechanism resides in the fragment planner service and its corresponding coordinator. Below is the unit test from bitchatTests/Services/BLEOutboundFragmentPlannerTests.swift that codifies the limit:

func testPrivateMediaV1AcceptsExactly256FragmentsAndRejects257() {
    let planner = BLEOutboundFragmentPlanner(mode: .privateMediaV1)
    
    // Boundary acceptance: 256 fragments allowed
    XCTAssertTrue(planner.acceptsFragments(count: 256))
    
    // Boundary rejection: 257 fragments blocked
    XCTAssertFalse(planner.acceptsFragments(count: 257))
}

The validation logic itself is implemented in bitchat/Services/BLEOutboundFragmentPlanner.swift, while bitchat/ViewModels/ChatMediaTransferCoordinator.swift orchestrates the transfer sequence, querying the planner to ensure files exceeding the 4 MiB threshold are halted before BLE transmission begins.

Practical Implementation for Developers

Before invoking the transfer coordinator, verify that the payload respects the protocol limits. The following Swift snippet demonstrates a pre-flight size check against the size cap for media transfers in BitChat:

import Foundation

func canTransferMedia(data: Data) -> Bool {
    let maxFragments = 256
    let fragmentSize = 16 * 1024 // 16 KiB per fragment
    let maxTransferSize = maxFragments * fragmentSize // 4,194,304 bytes
    
    return data.count <= maxTransferSize
}

// Example usage
let mediaData = UIImage(named: "photo.jpg")?.jpegData(compressionQuality: 0.9)
if let data = mediaData {
    if canTransferMedia(data: data) {
        // Safe to proceed with ChatMediaTransferCoordinator
        coordinator.startTransfer(data: data)
    } else {
        print("Error: Media exceeds BitChat 4 MiB transfer limit")
    }
}

Summary

  • Maximum Transfer Size: BitChat supports private media transfers up to 4 MiB (256 fragments × 16 KiB).
  • Enforcement Location: The cap is hardcoded in BLEOutboundFragmentPlanner.swift and strictly verified in BLEOutboundFragmentPlannerTests.swift.
  • Fixed Constraints: The fragment count cannot exceed 256, and each fragment size is fixed at 16 KiB by the BLE transport layer.
  • Coordinator Integration: ChatMediaTransferCoordinator.swift manages the transfer lifecycle but delegates size validation to the fragment planner's acceptsFragments(count:) method.

Frequently Asked Questions

What happens if I attempt to transfer a file larger than 4 MiB?

The transfer is rejected during initialization. Specifically, BLEOutboundFragmentPlanner.acceptsFragments(count:) returns false when the payload requires more than 256 fragments, causing ChatMediaTransferCoordinator to abort the operation before any BLE packets are transmitted.

Is the 16 KiB fragment size configurable?

No. The 16 KiB payload block is a constant defined within the BLE transport implementation in BLEOutboundFragmentPlanner.swift. Altering this value would require modifying the core library and updating the corresponding unit tests to maintain protocol integrity.

Does the 4 MiB cap apply to all file types?

Yes. The limit applies universally to all private media transfers—including images, audio, video, and documents—sent via the privateMediaV1 mode. The fragment planner enforces this boundary regardless of the file's MIME type or extension.

Where in the codebase can I verify the current media transfer limits?

Inspect the acceptsFragments(count:) method in bitchat/Services/BLEOutboundFragmentPlanner.swift and the associated boundary tests in bitchatTests/Services/BLEOutboundFragmentPlannerTests.swift. These files contain the authoritative logic for the 256-fragment and 4 MiB constraints.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →