Code 128 vs Code 39: Which Barcode Format Should You Use?
A detailed comparison of Code 128 and Code 39 barcodes — data capacity, character support, size efficiency, scanner compatibility, and which to choose for your application.
Code 128 and Code 39 are the two most widely used variable-length linear barcodes in non-retail applications — warehouses, manufacturing, healthcare, asset tracking, and logistics. Both are well-supported by virtually every scanner. So which one should you choose?
The short answer: Code 128 is almost always the better choice. But there are legitimate reasons to use Code 39, and understanding why helps you make the right call for your specific application.
Overview
| Feature | Code 128 | Code 39 |
|---|---|---|
| Year introduced | 1981 | 1974 |
| Character set | Full ASCII (128 chars) | 43 chars (A-Z, 0-9, 9 special) |
| Density | High (most efficient 1D barcode) | Low (longest barcode for same data) |
| Check digit | Built-in (mandatory) | Optional |
| Self-checking | No | Yes |
| Minimum X-dimension | 0.191mm | 0.191mm |
| Scanner support | Universal | Universal |
Code 39: The Original Open Standard
Code 39 was one of the first barcode symbologies developed, and it remains in use today due to its simplicity and long history of adoption in specific industries.
Character Set
Code 39 encodes:
- Uppercase letters A–Z
- Digits 0–9
- Space and 8 special characters:
-,.,$,/,+,%, and*(start/stop only)
What it cannot encode: lowercase letters, most special characters, or any character outside this 43-character set. This is the most significant limitation.
How It Works
Code 39 uses a simple, self-checking structure where each character is represented by 5 bars and 4 spaces (9 elements total), with 3 of these elements always being wide. The ratio of wide to narrow elements is typically 3:1, though it can range from 2:1 to 3:1.
The self-checking property means each character encodes redundancy — a single print defect is unlikely to produce a valid different character. This made Code 39 popular in early industrial applications where scanner reliability was a concern.
Size Disadvantage
Code 39 is significantly less space-efficient than Code 128. To encode the same data, a Code 39 barcode can be 2–3 times wider than the equivalent Code 128 barcode. For applications with constrained label space, this is a serious problem.
Example: Encoding “PART-12345” (10 characters):
- Code 39: approximately 60mm wide (at 0.254mm X-dimension)
- Code 128: approximately 28mm wide (at the same X-dimension)
When Code 39 Is Used
Despite its disadvantages, Code 39 appears in several industries due to historical standards:
- US Department of Defense (LOGMARS) — mandated Code 39 for military parts
- Automotive industry — AIAG standard uses Code 39
- Some healthcare applications — older hospital systems
- Simple asset tags — when data is short and uppercase-only
Code 128: The Modern Standard
Code 128 was designed to address Code 39’s limitations while maintaining scanner compatibility. It is significantly more efficient and flexible.
Character Set
Code 128 encodes the full 128 ASCII character set:
- All uppercase and lowercase letters
- All digits
- All standard punctuation and special characters
- Control characters (tab, line feed, etc.)
This makes Code 128 suitable for encoding serial numbers, mixed-case text, URLs, and any arbitrary string data.
Three Subsets (A, B, C)
Code 128 uses three internal encodings:
- Subset A: Control characters + uppercase + digits
- Subset B: Full printable ASCII + lowercase (most common)
- Subset C: Pairs of digits encoded with maximum efficiency (ideal for pure numeric data like GS1-128 application identifiers)
Modern barcode generators switch between subsets automatically to minimize barcode length.
Built-in Check Digit
Code 128 always includes a mandatory check digit, verified by the scanner on every read. This provides a mathematical guarantee against misreads — if the check digit doesn’t match, the scanner rejects the read rather than returning incorrect data.
GS1-128
GS1-128 (formerly EAN-128) is a subset of Code 128 with standardized data structures for supply chain use. It uses Application Identifiers (AIs) to encode specific data types:
- AI
(01)— GTIN - AI
(17)— expiry date - AI
(10)— batch/lot number - AI
(21)— serial number
GS1-128 is required on shipping labels for Walmart, Amazon, and most major retailers. It’s exclusively a Code 128 format.
Direct Comparison: Code 128 vs Code 39
Space Efficiency
Code 128 wins decisively. For any data longer than about 4 characters, Code 128 produces a smaller barcode. For numeric-only data using Subset C, Code 128 is approximately 3× smaller than Code 39.
Character Support
Code 128 wins. Code 39 cannot encode lowercase letters — if your data includes lowercase characters (product descriptions, URLs, mixed-case serial numbers), Code 39 simply cannot be used.
Scanner Compatibility
Both are essentially universal. Every 1D linear barcode scanner manufactured in the last 30 years supports both formats. This is not a deciding factor.
Error Detection
Code 128 wins. The mandatory check digit provides mathematical verification. Code 39’s self-checking property is weaker — it reduces misread probability but doesn’t provide the same guarantee.
Simplicity of Implementation
Code 39 has a slight edge in legacy and DIY contexts. The simpler encoding scheme made it easier to implement in firmware before modern barcode generator libraries existed. In 2024, this advantage is purely historical — you’re using a generator either way.
Industry Standards Compliance
Depends entirely on your industry. If your application must comply with LOGMARS, AIAG, or other standards that specify Code 39, you must use Code 39. Otherwise, Code 128 is the modern standard.
Decision Guide
Choose Code 128 if:
- Your data includes lowercase letters
- You need to encode more than ~6 characters
- Label space is limited
- You’re building a new system without legacy requirements
- You need GS1-128 compliance for retail/logistics
- You want mathematical error detection
Choose Code 39 if:
- An industry standard or trading partner explicitly requires it
- Your existing scanner infrastructure only reads Code 39 (very rare with modern equipment)
- You’re integrating with a legacy system that was built around Code 39
- Your data is all uppercase and under 6 characters and label space isn’t a concern
In practice: Unless you’re integrating with a system that specifies Code 39, use Code 128. The efficiency and character set advantages are significant, with zero compatibility downside.
Code 39 Full ASCII
There is an extended version called Code 39 Full ASCII that encodes all 128 ASCII characters by combining pairs of standard Code 39 characters. This is rarely used in practice because:
- It makes barcodes even longer (each full ASCII character requires two Code 39 characters)
- Not all decoders support the full ASCII extension
- Code 128 achieves the same character set more efficiently
Generating Code 128 and Code 39 Barcodes
Both formats are available in our barcode generator. Select “Code 128” or “Code 39” from the format dropdown and enter your data. For Code 39, the generator will alert you if you enter characters outside the supported set.
For shipping labels and supply chain use, use our dedicated Code 128 generator which supports GS1-128 formatting.
Summary
Code 128 replaced Code 39 as the dominant general-purpose linear barcode for good reason: it’s smaller, handles more characters, and provides stronger error detection. The only reason to choose Code 39 today is legacy compatibility with systems that specifically require it.
If you’re building anything new — inventory system, asset tracking, internal labeling — use Code 128. You’ll produce smaller, more reliable barcodes with full character set support.
Try the free barcode generator
Create professional barcodes and QR codes instantly. No registration required.