MainframeMaster

VB vs FB Datasets

On the mainframe, datasets are described by a record format (RECFM) and logical record length (LRECL). The two most common formats for DFSORT work are FB (Fixed Block) and VB (Variable Block). FB means every record has the same length; VB means each record can have a different length, with a 4-byte Record Descriptor Word (RDW) at the start of each record. Choosing the right format affects storage, performance, and compatibility with downstream programs. This page compares VB and FB, explains how DFSORT handles each, when to use which, and how to convert between them.

Data Types & Formats
Progress0 of 0 lessons

What FB and VB Mean

FB stands for Fixed Block. "Fixed" means every logical record has the same length; "Block" means multiple records are grouped into a single physical block on disk. So with RECFM=FB and LRECL=80, every record is exactly 80 bytes, and the system packs as many 80-byte records as fit into each block (e.g. BLKSIZE=27920 gives 349 records per block). There is no length prefix per record—the length is defined once in the DCB (LRECL).

VB stands for Variable Block. "Variable" means each record can have a different length; "Block" again means multiple records per physical block. Each record starts with a 4-byte RDW that contains the total length of that record (including the RDW). So the layout is: RDW (4 bytes) + data (variable bytes). The system uses the RDW to know how many bytes to read for that record. LRECL for VB is the maximum record length (including the 4-byte RDW), so the maximum data length is LRECL minus 4.

RECFM Values You Will See

RECFM can be a combination of characters. The main ones for DFSORT are:

Common RECFM values
RECFMMeaning
FFixed length, unblocked (one record per block). Rarely used.
FBFixed length, blocked. Multiple records per block. Most common for fixed-length files.
FBSFixed Block Standard: fixed length, blocked, with optional span (large records).
VVariable length, unblocked (one record per block).
VBVariable length, blocked. Multiple records per block. Standard for variable-length files.
VBSVariable Block Standard: variable length, blocked, with span support for very long records.

For typical DFSORT jobs, you use RECFM=FB when all records have the same length and RECFM=VB when record lengths vary. The "B" (blocked) form is preferred over F or V alone because blocking reduces I/O by reading and writing multiple records per physical block.

How DFSORT Treats FB and VB

DFSORT reads SORTIN and writes SORTOUT according to the dataset's RECFM and LRECL (from the DD statement or catalog). For fixed-length (FB) input, it reads exactly LRECL bytes per record. There is no RDW; position 1 in control statements is the first byte of the record. For variable-length (VB) input, it reads the 4-byte RDW, uses it to get the record length, then reads the data. Positions in SORT FIELDS, INREC, OUTREC, INCLUDE, and OMIT refer to the data portion only—position 1 is the first byte after the RDW. DFSORT does not strip the RDW on input or add it on output; it keeps the VB format intact when reading and writing VB.

When you allocate SORTOUT, you must set RECFM and LRECL to match what you are writing. If you use OUTREC to build a 60-byte fixed record, allocate SORTOUT with RECFM=FB and LRECL=60. If you write variable-length records (e.g. VB in, VB out with no length change), use RECFM=VB and an LRECL at least as large as the longest record.

LRECL: Fixed vs Variable

For FB (fixed-length)

LRECL is the length in bytes of every record. Example: LRECL=80 means every record is exactly 80 bytes. There is no per-record length field; the DCB defines the length once. When you change the output record length with OUTREC (e.g. build a 60-byte record from an 80-byte input), you must set SORTOUT LRECL=60 to match.

For VB (variable-length)

LRECL is the maximum record length, and that maximum includes the 4-byte RDW. So LRECL=256 means the longest record can be 256 bytes total: 4 bytes for the RDW plus up to 252 bytes of data. Shorter records are allowed; each record's actual length is stored in its RDW. When allocating a VB dataset for DFSORT output, set LRECL to the maximum record length you will write (including the RDW).

When to Use FB

  • Uniform record length. Every record is the same size (e.g. 80-byte card image, 100-byte fixed layout). FB is simple and avoids the overhead of an RDW per record.
  • Downstream expects fixed length. Many COBOL programs and legacy systems expect RECFM=FB and a fixed LRECL. Producing FB output ensures compatibility.
  • Reports with fixed line length. Printed reports often use fixed-length lines (e.g. 80 or 132 bytes). FB matches that model.
  • Sort keys at fixed positions. When every record has the same layout, key positions are the same for all records, which is straightforward for SORT FIELDS and INCLUDE/OMIT.

When to Use VB

  • Variable-length data. Records that naturally vary in length (free-form text, comments, or data that is only as long as needed). VB avoids padding short records to a fixed length and saves space.
  • Space efficiency. If most records are shorter than the maximum, VB uses less space than padding everything to the maximum with FB.
  • Output from programs that write variable length. Some applications (e.g. C, Java, or modern APIs) produce variable-length records; VB preserves that format through the sort.
  • Log or message files. Lines or messages of varying length are often stored in VB datasets.

Comparing FB and VB in Practice

FB vs VB at a glance
AspectFBVB
Record lengthSame for every record (LRECL).Varies per record; max = LRECL (incl. 4-byte RDW).
Per-record overheadNone.4-byte RDW per record.
Position 1 in DFSORTFirst byte of the record.First byte of data (after RDW).
Space for short recordsPadded to LRECL; can waste space.Only as long as needed; saves space.
Typical useCard image, fixed layout, reports, legacy I/O.Variable text, logs, variable-length output.

Converting Between VB and FB

You can produce fixed-length output from variable-length input by building a fixed-length record in OUTREC (or INREC) and allocating SORTOUT with RECFM=FB and the correct LRECL. For example, take the first 80 data bytes and pad with spaces if the input record is shorter; then SORTOUT with RECFM=FB, LRECL=80. Conversely, you can produce variable-length output from fixed-length input by building records of varying length and writing to a RECFM=VB dataset (with appropriate LRECL for the maximum). DFSORT's OUTFIL also supports VTOF (variable to fixed) and FTOV (fixed to variable) options for conversion when using multiple output files.

Example: copy variable-length input to a fixed 80-byte output (pad with spaces). You might use INREC or OUTREC to take bytes 1–80 of the data (or 1–L where L is the data length) and pad to 80, then allocate SORTOUT with RECFM=FB, LRECL=80. The exact build syntax depends on how you want to handle records shorter than 80 bytes (e.g. pad right with spaces).

text
1
2
3
OPTION COPY OUTREC FIELDS=(1,80) * or use BUILD with padding for short records * SORTOUT: RECFM=FB, LRECL=80

For VB input, positions in OUTREC refer to the data portion; 1,80 takes the first 80 data bytes. If the record has fewer than 80 data bytes, you may need BUILD with conditional logic or a product-specific way to pad. For simple "first 80 bytes, pad if shorter", refer to your DFSORT documentation for the exact BUILD or IFTHEN syntax.

JCL and DCB

In your JCL, SORTIN and SORTOUT need the correct DCB. For fixed-length:

text
1
2
3
//SORTIN DD DSN=MY.FB.FILE,DISP=SHR //SORTOUT DD DSN=MY.FB.OUT,DISP=(NEW,CATLG), // SPACE=(CYL,(10,5)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920)

For variable-length:

text
1
2
3
//SORTIN DD DSN=MY.VB.FILE,DISP=SHR //SORTOUT DD DSN=MY.VB.OUT,DISP=(NEW,CATLG), // SPACE=(CYL,(10,5)),DCB=(RECFM=VB,LRECL=256,BLKSIZE=27998)

If the dataset is cataloged, the catalog may supply RECFM and LRECL so you do not need DCB on the DD. For new datasets, always specify DCB to match what DFSORT will write.

RECORD Statement When Format Is Not Obvious

If DFSORT cannot determine the record format from the DD or dataset (e.g. tape or dynamic allocation without RECFM/LRECL), use the RECORD control statement. RECORD TYPE=F and LENGTH=80 tell DFSORT fixed-length 80-byte records; RECORD TYPE=V and LENGTH=256 tell it variable-length with maximum 256 (including RDW). For normal disk datasets with a proper DCB, RECORD is usually not needed.

Explain It Like I'm Five

Imagine a row of mailboxes. With FB, every mailbox is the same size. We know exactly where each box starts and ends, and we never need to look at a label to see how big a box is. With VB, each mailbox can be a different size. Each one has a small label (the RDW) that says "I am this many bytes long." So we read the label, then read that many bytes. FB is like a spreadsheet where every row is the same length; VB is like a list of sentences where each sentence can be as short or long as it needs to be. We use FB when everything is the same size, and VB when sizes are different so we don't waste space.

Exercises

  1. Your input is RECFM=VB, LRECL=300. What is the maximum number of data bytes in any one record?
  2. You use OUTREC to build a 100-byte fixed record. What RECFM and LRECL should SORTOUT have?
  3. When would you choose VB over FB for a sort output file? Give two reasons.
  4. For a VB dataset, does SORT FIELDS=(1,10,CH,A) sort on the first 10 bytes of the RDW or the first 10 bytes of the data? Explain.

Quiz

Test Your Knowledge

1. What does the "B" in FB and VB stand for?

  • Binary
  • Blocked: multiple records are stored in a single physical block
  • Byte
  • Buffer

2. For RECFM=VB, what does LRECL represent?

  • The exact length of every record
  • The maximum record length, including the 4-byte RDW
  • The average record length
  • The data length only (excluding RDW)

3. When would you choose VB over FB for a DFSORT output?

  • When you need faster sort performance
  • When record lengths vary and you want to avoid padding short records to a fixed length
  • When the downstream program only accepts FB
  • VB is never used for sort output

4. In DFSORT control statements, does position 1 for a VB record include the RDW?

  • Yes; position 1 is the first byte of the RDW
  • No; position 1 is the first byte of the data after the 4-byte RDW
  • Only for SORT FIELDS
  • Only when using RECORD TYPE=V

5. What RECFM would you use for an 80-byte card-image file where every record is 80 bytes?

  • RECFM=VB, LRECL=84
  • RECFM=FB, LRECL=80
  • RECFM=V, LRECL=80
  • RECFM=VB, LRECL=80