Simply put, the code rate can be defined as the ratio of the data rate that is allocated for a subframe and the maximum data rate that ideally can be allocated in the subframe. In other words, it means "The code rate is defined as the ratio between the transport block size and the total number of physical layer bits per subframe that are available for transmission of that transport block". A lower code rate means that more redundency bits are inserted during the channel coding process and a higher code rate means that less redundency bits are insterted.
- Is there any theoretical limit for Code Rate ?
- Example of Code Rate Calculation
- TTCN Code for Code Rate Calculation
- Code Rate vs MCS in LTE
- Reference
Exact Calculation of Code Rate would be a little tricky and explaining the calculation method in writing may be even more tricky. If you are the type of person (like me) who can grasp the meaning from visualized from, refer to following illustration first and then try to read the rest of this page.

Every clause number needed to compute a code rate by hand, on one drawing. The numerator comes in at the top left and the denominator is counted on the grid at the right.
Ten numbered blocks, each carrying its own clause : steps 1 to 5 are the 36.212 coding chain. They run from Transport Block CRC Attachment at 5.3.2.1 through to Code block concatenation at 5.3.2.5.Steps 6 to 10 cross into 36.211 : Scrambling at 6.3.1, Modulation at 6.3.2, Layer Mapping and Precoding at 6.3.3 and 6.3.4, and Resource Element Mapping at 6.3.5.The note at the top left names where the numerator comes from : TBS defined in 36.213 Table 7.1.7.2.1-1. Its arrow points at User Data and at the bit sequence a0 to aA-1.The green note on the grid is the denominator : Number of PDSCH RE = Number of Yellow RE − Number of Red RE. Yellow is what the allocation gives you and red is what other signals take back.The red note converts REs into bits : Number of Bits in PDSCH = Number of PDSCH RE x Number of Bits/RE. The Qm value comes from 36.213 Table 7.1.7.1-1.The purple line at the bottom is the whole formula : Code Rate for PDSCH = [A + 24(CRC Bits)] / (Number of Bits in PDSCH). Everything above it exists to fill in those two quantities.
Is there any theoretical limit for Code Rate ?
There is no hard ceiling in the mathematics, because a code rate above one simply means the transport block is larger than the room it was given. Instead there is a point beyond which the specification stops requiring the UE to try. That point is a single number, and the rest of this section is about where it sits and what happens either side of it.
I think this question would imply "Is there any theoretical Max Code Rate that would achive max throughput with minimum BER (or zero BER : Bit Error Rate) ?".
The relation between Code Rate and BER is a kind of statistical (probablistic) relation.. it is hard to find a clear cut value for this answer. When it comes to reality, the situation gets even more blurry since the performance of the reciever comes into play as well.
However, there is a guideline in 3GPP specification. TS36.213 7.1.7 Modulation order and transport block size determination and it says as follows.
The UE may skip decoding a transport block in an initial transmission if the effective channel code rate is higher than 0.930, where the effective channel code rate is defined as the number of downlink information bits (including CRC bits) divided by the number of physical channel bits on PDSCH. If the UE skips decoding, the physical layer indicates tohigher layer that the transport block is not successfully decoded. For the special subframe configurations 0 and 5 with normal CP or configurations 0 and 4 with extended CP, shown in table 4.2-1 of TS 36.211: "Evolved Universal Terrestrial Radio Access (E-UTRA); Physical channels and modulation", there shall be no PDSCH transmission in DwPTS of the special subframe.
One note on that quotation before going on, because the number in it has moved. The passage above is from the release the author was reading. In 36.213 v19.4.0 the same sentence of clause 7.1.7 reads
Two thousandths make no difference to any of the reasoning below. The number you quote is still worth getting right, though. A test that fails at 0.931 fails for a different reason depending on which release the equipment follows.
Based on this, I did some experiement with one of my reference device and eNB simulator. The test condition and the result is as follows.
- System BW = 15 Mhz
- Number of RB = 75
- MCS = 28
- DUT to Equipment Connection : Conductive and Downlink Power is high (meaning SNR is very good)
- Downlink 256 QAM : Disabled
- CFI vs Code Rate (Following is for the subframe with no PBCH)
|
CFI |
3 |
2 |
1 |
|
A |
55056 |
55056 |
55056 |
|
Number of Bits in PDSCH |
54000 |
59400 |
64800 |
|
Code Rate |
1.020 |
0.927 |
0.850 |
One transport block size against three control region sizes. The numerator never moves, so the whole of the change comes from how many symbols are left after PDCCH has taken its share.
A is held constant at 55056 bits : the same transport block is scheduled in all three columns, which is what makes the comparison clean.Only the denominator moves : 54000 bits at CFI = 3, 59400 at CFI = 2 and 64800 at CFI = 1. Each symbol handed back to PDSCH is worth about 5400 bits here.The CFI = 3 column is above one : 1.020 means the transport block does not fit in the resources allocated for it. No amount of decoding effort can recover it.CFI = 2 sits just under the specification's threshold : 0.927 against 0.930, which is why the author sees small numbers of CRC errors rather than none.CFI = 1 is the only comfortable column : 0.850 leaves real margin, and it is the setting that gave clean throughput.The conditions matter as much as the numbers : conductive connection, high downlink power and 256 QAM disabled. This is a best case for SNR, so the errors that appear are a coding limit rather than a radio one.
As you may guess, I got the best throughput with no CRC error with CFI = 1. I got pretty good throughput at CFI = 2 as well but I start see small portions of CRC error. If you don't decrease MCS at the subframe with PBCH, you would get much higher CRC error. We can say this result is pretty well aligned with the guideline described in 3GPP.
With CFI = 3, my reference device still tries to decode PDSCH even though Code Rate is very high (Based on my experience, all the Devices try to decode anyway however high code rate it is), but too high CRC error that leads to call drop.
The threshold is permission to give up, not a ban : the specification says the UEmay skip decoding above it. A device that keeps trying is still compliant.Above 1.0 the block cannot fit at all : that is arithmetic rather than policy, and it is what the CFI = 3 column shows.CFI is the lever the network actually has : the transport block size is chosen first, and the control region then decides whether it fits.The number moved between releases : 0.930 in the text quoted here, 0.932 in 36.213 v19.4.0.
Example of Code Rate Calculation
Two walkthroughs follow, and they reach different numbers on purpose. The first counts resource elements the careful way and subtracts the control region. The second is an idealised count that keeps every symbol. Knowing which assumption each one makes is more useful than either answer.
Let's take an example with MCS = 8 and No of RBs = 3.
For this we have to get the two numbers based on specification quoted above.
(i) number of downlink information bits (including CRC bits )
(ii) number of physical channel bits
(i) refers to "(Transport Block Size + CRC bits)" which is the size of the message that gets channel coded.
(ii) refers to the number of available bits in the PHYSICAL LAYER. Each resource element(RE) can carry 2, 4, or 6 bits depending on the modulation scheme.We just have to count the number of REs reserved for PDSCH transmission on each subframe, and then multiply it by 2, 4, or 6 (accordint to modulation scheme) and then we will have the number of physical channel bits on PDSCH.
Getting back to our example condition MCS = 8 and No of RBs = 3. In this case,
for item (i), we can easily figure this out from TS36.213 Table7.1.7.1-1
for item (ii) we have
a) 3 x 12 REs/symbol
b) (14 symbols/subframe) x (3 x 12 REs/symbols) = 504 REs/subframe. Out of this 504 REs, we have to remove those REs allocated for PDCCH since it is not carrying the real data. Let's assume that 3 symbols/subframe are allocated for PDCCH. In this case, the number of REs for avaiable in PHY LAYER for data transmission is 504 - (3 x (3 x 12)) which is 396. Now we have to convert this number into "number of bits". In our sample case, the modulation scheme is QPSK which carries 2 bits per RE. Therefore, the value for item (ii) is 2 x 396 = 792. This assumes that the subframe does not carry PBCH, PSS, SSS. If it is the subframe that carries these signals, we have to remove the REs for PBCH, PSS, SSS as well.
Now we have the value (i) and (ii). If you take (i)/(ii), you will get the Code Rate.
I admit the explanation above would sound too complicated and messy. I asked on this to another expert on this area and he gave me much clearer explanation as follows :
The code rate is the result (consequence) of the combination of TBS, MCS, and N_RB we have chosen for the transmission. Effective channel code rate is defined as the number of downlink information bits (including CRC bits) divided by the number of physical channel bits on PDSCH
Let us take the caseMCS=8; ITBS=8, TBS=808; N_PRB=6
The number of downlink information bits =808+24 (CRC bits) = 832. The number of physical channel bits on PDSCH = 6 (N_PRB)*12(no. of subcarriers in a PRB)*7(number of OFDM symbols in a slot)*2(no. of slots in a subframe)*2(number of bits per modulated symbols)=2016
Effective channel code rate = 832/2016 = 0.4127
The two calculations are worth putting side by side. The page arrives at 792 physical channel bits in one and 2016 in the other, and the number of resource blocks is not the only reason.
The first walkthrough takes 3 resource blocks and counts 14 symbols, which gives 504 REs. It then removes three symbols for PDCCH to leave 396, and multiplies by 2 bits per RE for QPSK. The second takes 6 resource blocks and keeps all 14 symbols, giving 6 × 12 × 14 × 2 = 2016. So one subtracts a control region and the other does not.
Neither removes the reference signal REs. The drawing near the top of this page is stricter than both of them. Its green note takes the red REs out of the yellow ones before counting. That difference is exactly what the next section's constant is for.
The second example does check out against the current specification, field for field. 36.213 Table 7.1.7.1-1 maps MCS 8 to modulation order 2 and TBS index 8. Table 7.1.7.2.1-1 gives 808 bits for TBS index 8 at 6 resource blocks. 808 plus 24 CRC bits is 832, and 832 divided by 2016 is 0.4127.
The numerator is the easy half : look up the transport block size, add 24 CRC bits, and stop. Both walkthroughs agree on how to do it.The denominator is the half they disagree on : every count of usable REs depends on what you are willing to subtract.Two lookups, not one : Table 7.1.7.1-1 turns MCS into a modulation order and a TBS index. Table 7.1.7.2.1-1 turns that index and the resource block count into bits.The worked example is correct : MCS 8, TBS index 8, 808 bits at 6 RBs, 832 over 2016, 0.4127. Every step checks against 36.213 v19.4.0.
TTCN Code for Code Rate Calculation
Conformance test code has to settle every question the prose above leaves open, because it has to produce a number. So the listing below is worth reading as a set of decisions rather than as a program. One constant in it does the work of the whole resource element argument.
Still now clear ? Don't worry, you are not the only one who get confused. I am also one of them.
I just found a useful source clips from LTE Protcol Conformance TTCN (MAC_717.ttcn). For many engineers, one source code would worth 1000 words.
TTCN-3 from the LTE protocol conformance suite, MAC_717.ttcn, quoted as the author found it. It is a source listing rather than specification text, so nothing in it has been corrected.
function fl_CalculateCodingRate ( integer p_I_MCS,
integer p_N_PRB,
integer p_TBSize) return boolean
{
const integer tsc_REs_Per_PRB := 138; /* @sic R5s100155 sic@
* 12 * 12 - 6 [Cell specific reference symbols] total 8, and 2 in symbols 0]
* with DCI =2, symbols o and 1 are used for REGs */
var integer v_BitsPerSymbol;
var float v_CodingRate;
// initialise v_BitsPerSymbol
if (p_I_MCS < 10)
{
v_BitsPerSymbol := 2 ; //QPSK
}
else if (p_I_MCS < 17)
{
v_BitsPerSymbol := 4 ; //16QAM
}
else if (p_I_MCS < 29)
{
v_BitsPerSymbol := 6 ; //64QAM
}
else
{
FatalError(__FILE__, __LINE__, "invalid imcs");
}
v_CodingRate := (int2float(p_TBSize + 24)) / (int2float(p_N_PRB * tsc_REs_Per_PRB * v_BitsPerSymbol));
if ( v_CodingRate <= 0.930)
{
return true; // TB size applicable
}
else
{
return false; // Coding rate is high hence TB size is not applied
}
} // end of f_CalculateCodingRate
The constant on the first line of the function body is the interesting part. The assignment
Compare that with the raw figure. A resource block over a full subframe holds 12 subcarriers times 14 symbols, which is 168 resource elements. The test assumes 138 of those reach PDSCH, so 30 per resource block are taken by the control region and the reference signals together.
That single number is why the code can be so short. It replaces the whole of the counting argument in the section above with one agreed figure. That is what a conformance test needs: not the most accurate count, but the same count on every tester.
The code answers the question the prose could not : it fixes the RE count at 138 per resource block and moves on.168 is the raw number and 138 is the usable one : 12 subcarriers by 14 symbols, less 30 REs for control and reference signals.The modulation order comes from three MCS thresholds : below 10 is QPSK, below 17 is 16QAM, below 29 is 64QAM, and anything else is a fatal error.The return value is a verdict, not a rate : the function compares the result against 0.930 and answers whether the transport block size is applicable.A fixed constant is a deliberate simplification : it is repeatable across testers, which matters more in conformance than being right to the last RE.
As you see in the code above, the basic formula for code rate is
Code Rate = (Transport Block Size + Size of CRC Bits)/(Total number of REs x Number of Bits per Symbol)
The equation itself would look simple, but real calculation is not that simple mainly because it is hard figure out 'Total number of REs'. This 'RE (Resource Elements)' is the one that can carry PDSCH or PUSCH data. The REs carrying other bits (e.g, RS, PHICH, PDCCH, SRS etc) are not counted. Even though you allocated the same number of RBs and MCS, the number of REs within the allocated block would get different depending on various situation as follows :
i) Is it Uplink or Downlink (Frame Structure for UL/DL is different)
ii) How many symbols are allocated for control channel (PCFICH value) for Downlink ?
iii) What is transmission mode ? (Depending on Transmission mode, number of symbols for Reference Signal would vary)
iv) Does it carry SRS (Uplink) ?
etc
For more practical examples, refer to Reiver He's LTE Note : LTE FDD DL code rate calculation. You would see every detailed factors you need to consider if you want to calculate Code rate by hand.
Code Rate vs MCS in LTE
Plotting code rate against MCS produces a shape most people do not expect. It does not climb steadily from one end to the other. It climbs, drops hard, climbs again, drops again, and the drops are where the modulation order changes.
Followings are the code rate for each MCS in LTE assuming that the System Bandwidth is 20 Mhz and 100 RBs are allocated and 256 QAM is not supported. The exact code rate value would change a little bit, but the variation would be roughly within 1%.
|
MCS |
I_TBS |
Modulation |
TBS |
User Data |
Code Rate |
|
100 PRBs |
100 PRBs |
||||
|
0 |
0 |
QPSK |
2,792 |
30,000 |
0.094 |
|
1 |
1 |
QPSK |
3,624 |
30,000 |
0.122 |
|
2 |
2 |
QPSK |
4,584 |
30,000 |
0.154 |
|
3 |
3 |
QPSK |
5,736 |
30,000 |
0.192 |
|
4 |
4 |
QPSK |
7,224 |
30,000 |
0.242 |
|
5 |
5 |
QPSK |
8,761 |
30,000 |
0.293 |
|
6 |
6 |
QPSK |
10,296 |
30,000 |
0.344 |
|
7 |
7 |
QPSK |
12,216 |
30,000 |
0.408 |
|
8 |
8 |
QPSK |
14,112 |
30,000 |
0.471 |
|
9 |
9 |
QPSK |
15,840 |
30,000 |
0.529 |
|
10 |
9 |
16 QAM |
15,840 |
60,000 |
0.264 |
|
11 |
10 |
16 QAM |
17,658 |
60,000 |
0.295 |
|
12 |
11 |
16 QAM |
19,848 |
60,000 |
0.331 |
|
13 |
12 |
16 QAM |
22,920 |
60,000 |
0.382 |
|
14 |
13 |
16 QAM |
25,456 |
60,000 |
0.425 |
|
15 |
14 |
16 QAM |
28,336 |
60,000 |
0.473 |
|
16 |
15 |
16 QAM |
30,576 |
60,000 |
0.510 |
|
17 |
15 |
64QAM |
30,576 |
90,000 |
0.340 |
|
18 |
16 |
64QAM |
32,856 |
90,000 |
0.365 |
|
19 |
17 |
64QAM |
36,696 |
90,000 |
0.408 |
|
20 |
18 |
64QAM |
39,232 |
90,000 |
0.436 |
|
21 |
19 |
64QAM |
43,816 |
90,000 |
0.487 |
|
22 |
20 |
64QAM |
46,888 |
90,000 |
0.521 |
|
23 |
21 |
64QAM |
51,024 |
90,000 |
0.567 |
|
24 |
22 |
64QAM |
55,056 |
90,000 |
0.612 |
|
25 |
23 |
64QAM |
57,336 |
90,000 |
0.637 |
|
26 |
24 |
64QAM |
61,664 |
90,000 |
0.685 |
|
27 |
25 |
64QAM |
63,776 |
90,000 |
0.709 |
|
28 |
26 |
64QAM |
75,326 |
90,000 |
0.837 |
Read the fourth column down the table and the sawtooth appears before the plot draws it. The denominator jumps whenever the modulation column changes, and the code rate falls with it.
Following plot shows the relation between MCS and Code Rate based on the table show above.

Three bands, two drops. A higher MCS always carries more bits, but it does not always mean a higher code rate, and the two drops are the reason.
The bands are the modulation schemes : QPSK shaded yellow over MCS 0 to 9, 16 QAM shaded pink over 10 to 16, and 64 QAM shaded green over 17 to 28.The axes are plain : MCS along the bottom from 0 to 28, CODE RATE up the side from 0.000 to 1.000.Inside each band the curve rises steadily : the transport block grows while the number of physical channel bits stays fixed, so the ratio climbs.At each band edge the curve drops : 0.529 at MCS 9 down to 0.264 at MCS 10, and 0.510 at MCS 16 down to 0.340 at MCS 17.The drops come from the denominator : bits per RE go 2, then 4, then 6. The same transport block suddenly has far more room.The top of the range is the only part near the limit : MCS 28 reaches 0.837, still under the threshold from the first section.
MCS is not a code rate dial : it sets a transport block size and a modulation order together, and the code rate is what falls out.The lowest code rates sit just above a modulation change : MCS 10 and MCS 17 are the most protected points in the whole range.Two MCS values can give the same code rate : the sawtooth crosses its own levels, so a code rate alone does not identify an MCS.The table and the plot are the same data : the plot is worth having because the drops are hard to see in a column of numbers.
Reference
- 36.213 : 3GPP - E-UTRA; Physical layer procedures, v19.4.0. Clause 7.1.7 (modulation order and transport block size determination, including the effective channel code rate threshold), Table 7.1.7.1-1 (modulation and TBS index table for PDSCH) and Table 7.1.7.2.1-1 (transport block size table).
- 36.212 : 3GPP - E-UTRA; Multiplexing and channel coding, v19.3.0. Clauses 5.3.2.1 to 5.3.2.5, the coding chain drawn as steps 1 to 5 in the figure near the top of this page.
- 36.211 : 3GPP - E-UTRA; Physical channels and modulation, v19.3.0. Clauses 6.3.1 to 6.3.5, drawn as steps 6 to 10 in the same figure, and Table 4.2-1 for the special subframe configurations named in the quotation above.