{"id":93166,"date":"2022-01-20T21:01:53","date_gmt":"2022-01-20T21:01:53","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=93166"},"modified":"2026-03-09T12:37:47","modified_gmt":"2026-03-09T12:37:47","slug":"when-use-char-varchar-varcharmax","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/when-use-char-varchar-varcharmax\/","title":{"rendered":"CHAR vs VARCHAR vs VARCHAR(MAX) in SQL Server"},"content":{"rendered":"\n<p>Use <code>CHAR<\/code> for fixed-length data like state codes, phone numbers, or postal codes where every value is the same length &#8211; it pads shorter values with spaces and uses consistent storage. Use <code>VARCHAR<\/code> for variable-length data like names, addresses, or descriptions where lengths vary significantly &#8211; it stores only the characters entered plus 2 bytes of overhead.<\/p>\n\n\n\n<p>Use <code>VARCHAR(MAX)<\/code> when you need to store strings longer than 8,000 bytes (up to 2 GB), typically for large text fields, XML fragments, or JSON documents. <code>CHAR<\/code> is faster for fixed-width data; <code>VARCHAR<\/code> is more space-efficient for variable data; <code>VARCHAR(MAX)<\/code> has different storage and query plan behavior than standard <code>VARCHAR<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-introduction\">Introduction<\/h2>\n\n\n\n<p>In every database, there are different kinds of data that need to be stored. Some data is strictly numeric, while other data consists of only letters or a combination of letters, numbers, and even special symbols. Whether it is just stored in memory or on disk, each piece of data requires a data type. Picking the correct data type depends on the characteristics of the data being stored. This article explains the differences between <code>CHAR<\/code>, <code>VARCHAR<\/code>, and <code>VARCHAR(MAX)<\/code>&nbsp;in SQL Server.<\/p>\n\n\n\n<p>When selecting a data type for a column, you need to think about the characteristics of the data to pick the correct data type. Will each value be the same length, or will the size vary greatly between values? How often will the data change? Will the length of the column change over time? There might also be other factors, like space efficiency and performance, that might drive your decision on a data type.<\/p>\n\n\n\n<p>The <code>CHAR<\/code>, <code>VARCHAR<\/code>, and <code>VARCHAR(MAX)<\/code> data types can store character data. This article will discuss and compare these three different character data types. The information found in this article will help you decide when it is appropriate to use each of these data types.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-char-the-fixed-length-character-data-type\">CHAR the fixed-length character data type<\/h2>\n\n\n\n<p>The CHAR data type is a fixed-length data type. It can store characters, numbers, and special characters in strings up to 8000 bytes in size. <code>CHAR<\/code> data types are best used for storing data that is of a consistent length. For example, two-character State codes in the United States, single-character sex codes, phone numbers, postal codes, etc. A <code>CHAR<\/code> column would not be a good choice for storing data where the length varies greatly. Columns storing things like addresses or memo fields would not be suitable for a <code>CHAR<\/code> column data type.<\/p>\n\n\n\n<p>This doesn\u2019t mean a <code>CHAR<\/code> column can\u2019t contain a value that varies in size. When a <code>CHAR<\/code> column is populated with strings shorter than the length of the column, spaces will be padded to the right. The number of spaces padded is based on the size of the column less the length of characters being stored. Because <code>CHAR<\/code> columns are fully populated by adding spaces, when needed, each column uses the same amount of disk space or memory. Trailing spaces also make it a challenge when searching and using <code>CHAR<\/code> columns. More on this in a moment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-varchar-variable-length-character-data-type\">What is VARCHAR (variable-length character data type)?<\/h2>\n\n\n\n<p><code>VARCHAR<\/code> columns, as the name implies, store variable-length data. They can store characters, numbers, and special characters just like a <code>CHAR<\/code> column and can support strings up to 8000 bytes in size. A variable-length column only takes up the space it needs to store a string of characters, with no spaces added to pad out the column. For this reason, <code>VARCHAR<\/code> columns are great for storing strings that vary greatly in size.<\/p>\n\n\n\n<p>To support variable-length columns, the length of the data needs to be stored along with the data. Because the length needs to be calculated and used by the database engine when reading and storing variable-length columns, they are considered a little less performant than <code>CHAR<\/code> columns. However, when you consider they only use the space they need, the savings in disk space alone might offset the performance cost of using a <code>VARCHAR<\/code> column.<\/p>\n\n\n\n<p><strong>Read also:<\/strong><br><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/temporary-tables-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">Temporary tables and data type selection in SQL Server<\/a><br><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/ai-in-sql-server-2025-embeddings\/\" target=\"_blank\" rel=\"noreferrer noopener\">AI embeddings in SQL Server 2025<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-differences-between-char-and-varchar-data-types\">Differences between CHAR and VARCHAR data types<\/h2>\n\n\n\n<p>The fundamental difference between <code>CHAR<\/code> and <code>VARCHAR<\/code> is that the <code>CHAR<\/code> data type is fixed in length, while the <code>VARCHAR<\/code> data type supports variable-length columns of data. But they are also similar. They both can store alphanumeric data. To better understand the differences between these two data types, review the similarities and differences found in Table 1.<\/p>\n\n\n\n<p><strong>Table 1: Differences between CHAR and VARCHAR<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>\n<p><strong>CHAR<\/strong><\/p>\n<\/td><td>\n<p><strong>VARCHAR<\/strong><\/p>\n<\/td><\/tr><tr><td>\n<p>Used to store strings of fixed size<\/p>\n<\/td><td>\n<p>Used to store strings of variable length<\/p>\n<\/td><\/tr><tr><td>\n<p>Can range in size from 1 to 8000 bytes<\/p>\n<\/td><td>\n<p>Can range in size from 1 to 8000 bytes<\/p>\n<\/td><\/tr><tr><td>\n<p>Uses a fixed amount of storage, based on the size of the column<\/p>\n<\/td><td>\n<p>Use varying amounts of storage space based on the size of the string stored.<\/p>\n<\/td><\/tr><tr><td>\n<p>Takes up 1 to 4 byte for each character, based on collation setting<\/p>\n<\/td><td>\n<p>Takes up 1 to 4 byte for each character based on collation and requires one or more bytes to store the length of the data<\/p>\n<\/td><\/tr><tr><td>\n<p>Better performance<\/p>\n<\/td><td>\n<p>Slightly poorer performance because length has to be accounted for.<\/p>\n<\/td><\/tr><tr><td>\n<p>Pads spaces to the right when storing strings less than the fixed size length<\/p>\n<\/td><td>\n<p>No padding necessary because it is variable in size<\/p>\n<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-does-the-n-mean-in-char-n-or-varchar-n\">What does the \u201cN\u201d mean in CHAR(N) or VARCHAR(N)<\/h2>\n\n\n\n<p>The \u201cN\u201d does not mean the maximum number of characters that can be stored in a <code>CHAR<\/code> or <code>VARCHAR<\/code> column but instead means the maximum number of bytes a data type will take up. SQL Server has different collations for storing characters. Some character sets, like <em>Latin,<\/em> store each character in one byte of space. In contrast, other character sets, like the one for Japanese, require multiple bytes to store a character.<\/p>\n\n\n\n<p><code>CHAR<\/code> and <code>VARCHAR<\/code> columns can store up to 8000 bytes. If a single-byte character set is used, up to 8000 characters can be stored in a <code>CHAR<\/code> or <code>VARCHAR<\/code> column. If a multi-byte collation is used, the maximum number of characters that a <code>VARCHAR<\/code> or <code>CHAR<\/code> can store will be less than 8000. A discussion on collation is outside the scope of this article, but if you want to find out more about single and multi-byte character sets, then check out <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/collations\/collation-and-unicode-support?view=sql-server-ver15\">this<\/a> documentation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-truncation-error\">Truncation error<\/h2>\n\n\n\n<p>When a column is defined as a <code>CHAR(N)<\/code> or <code>VARCHAR(N)<\/code>, the \u201cN\u201d represents the number of bytes that can be stored in the column. When populating a <code>CHAR(N)<\/code> or <code>VARCHAR(N)<\/code> column with a character string, a truncation error like shown in Figure 1 might occur.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"808\" height=\"48\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/01\/word-image-6.png\" alt=\"\" class=\"wp-image-93167\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 1: Truncation error<\/strong><\/p>\n\n\n\n<p>This error occurs when trying to store a string longer than the maximum length of a <code>CHAR<\/code> or <code>VARCHAR<\/code> column. When a truncation error like this occurs, the TSQL code terminates, and any following code will not be executed. This can be demonstrated using the code in Listing 1.<\/p>\n\n\n\n<p><strong>Listing 1: Code to produce truncation error<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE tempdb;\nGO\nCREATE TABLE MyTable (A VARCHAR(10));\nINSERT INTO MyTable VALUES ('This String');\n-- Continue on \nSELECT COUNT(*) FROM MyTable;\nGO<\/pre>\n\n\n\n<p>The code in Listing 1 produced the error in Figure 1 when the <code>INSERT<\/code> statement is executed. The <code>SELECT<\/code> statement following the <code>INSERT<\/code> statement was not executed because of the truncation error. The truncation error and script termination might be exactly the functionality you might want, but there are times when you might not want a truncation error to terminate your code.<\/p>\n\n\n\n<p>Suppose there is a need to migrate data from an old system to a new system. In the old system, there is a table MyOldData that contains data created using the script in Listing 2.<\/p>\n\n\n\n<p><strong>Listing 2: Table in old system<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE tempdb;\nGO\nCREATE TABLE MyOldData (Name VARCHAR(20), ItemDesc VARCHAR(45));\nINSERT INTO MyOldData \nVALUES ('Widget', 'This item does everything you would ever want'), \n       ('Thing A Ma Jig', 'A thing that dances the jig');\nGO<\/pre>\n\n\n\n<p>The plan is to migrate the data in <em>MyOldData<\/em> table to a table named <em>MyNewTable,<\/em> which has a smaller size for the <code>ItemDesc<\/code> column. The code in Listing 3 is used to create this new table and migrate the data.<\/p>\n\n\n\n<p><strong>Listing 3: Migrating data to a new table<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE tempdb;\nGO \nCREATE TABLE MyNewData (Name VARCHAR(20), ItemDesc VARCHAR(40));\nINSERT INTO MyNewData SELECT * FROM MyOldData;\nSELECT * FROM MyNewData;\nGO<\/pre>\n\n\n\n<p>When the code in Listing 3 is run, you get a truncation error similar to the error in Figure 1, and no data is migrated.<\/p>\n\n\n\n<p>In order to successfully migrate the data, you need to determine how to deal with the data truncation to make sure all rows migrate across. One method is to truncate the item description using the <code>SUBSTRING<\/code> function by running the code in Listing 4.<\/p>\n\n\n\n<p><strong>Listing 4: Eliminating truncation error with SUBSTRING<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">DROP Table MyNewData\nGO\nUSE tempdb;\nGO \nCREATE TABLE MyNewData (Name VARCHAR(20), ItemDesc VARCHAR(40));\nINSERT INTO MyNewData SELECT Name, substring(ItemDesc,1,40) \nFROM MyOldData;\nSELECT * FROM MyNewData;\nGO<\/pre>\n\n\n\n<p>When running the code in Listing 4, all records are migrated. Those with an <code>ItemDesc<\/code> longer than 40 will be truncated using the <code>SUBSTRING<\/code> function, but there is another way.<\/p>\n\n\n\n<p>If you want to avoid the truncation error without writing special code to truncate columns that are too long, you can set the <code>ANSI_WARNINGS<\/code> setting to off, as done in Listing 5.<\/p>\n\n\n\n<p><strong>Listing 5: Eliminating truncation error by setting ANSI_WARNINGS to off.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">DROP Table MyNewData\nGO\nUSE tempdb;\nGO \nCREATE TABLE MyNewData (Name VARCHAR(20), ItemDesc VARCHAR(40));\nSET ANSI_WARNINGS OFF;\nINSERT INTO MyNewData SELECT * FROM MyOldData;\nSET ANSI_WARNINGS ON;\nSELECT * FROM MyNewData;\nGO<\/pre>\n\n\n\n<p>By setting the <code>ANSI_WARNINGS<\/code> off, the SQL Server engine does not follow the ISO standard for some error conditions, one of those being the truncation error condition. When this setting is turned off, SQL Server automatically truncates the source column to fit in target columns without producing an error. Care should be used when turning off <code>ANSI_WARNINGS<\/code> because other errors might also go unnoticed. Therefore, changing the <code>ANSI_WARNING<\/code> setting should be used cautiously.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-varchar-max\">VARCHAR(MAX)<\/h2>\n\n\n\n<p>The <code>VARCHAR(MAX)<\/code> data type is similar to the <code>VARCHAR<\/code> data type in that it supports variable-length character data. <code>VARCHAR(MAX)<\/code> is different from <code>VARCHAR<\/code> because it supports character strings up to 2 GB (2,147,483,647 bytes) in length. You should consider using <code>VARCHAR(MAX)<\/code> only when each string stored in this data type varies considerably in length, and a value might exceed 8000 bytes in size.<\/p>\n\n\n\n<p>You might be asking yourself, why not use <code>VARCHAR(MAX)<\/code> all the time, instead of using <code>VARCHAR<\/code>? You could, but here are a few reasons why you might not want to do that:<\/p>\n\n\n\n<p><code>VARCHAR(MAX)<\/code> columns cannot be included as a key column of an index.<\/p>\n\n\n\n<p><code>VARCHAR(MAX)<\/code> columns do not allow you to restrict the length of the column.<\/p>\n\n\n\n<p>In order to store large strings, <code>VARCHAR(MAX)<\/code> columns use LOB_DATA allocation units for large strings. <code>LOB_DATA<\/code> storage is much slower than using <code>IN_ROW_DATA<\/code> storage allocation units.<\/p>\n\n\n\n<p><code>LOB_DATA<\/code> storage doesn\u2019t support page and row compression.<\/p>\n\n\n\n<p>You might be thinking <code>VARCHAR(MAX)<\/code> columns will eliminate the truncation error that we saw earlier. That is partially true, provided you don\u2019t try to store a string value longer than 2,147,483,647 bytes. If you do try to store a string that is longer than to 2,147,483,647 bytes in size, you will get the error shown in Figure 2.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>\n<figure><img loading=\"lazy\" decoding=\"async\" width=\"745\" height=\"44\" class=\"wp-image-93168\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/01\/word-image-7.png\"><\/figure><p><\/p>\n<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Figure 2: Error when a string is longer than 2 GB in size<\/strong><\/p>\n\n\n\n<p>You should only use <code>VARCHAR(MAX)<\/code> columns when you know some of the data you are going to store exceed the 8000-byte limit of a <code>VARCHAR(N)<\/code> column, and all of the data is shorter than the 2 GB limit for the <code>VARCHAR(MAX)<\/code> column.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-concatenation-problems-with-char-columns\">Concatenation problems with CHAR Columns<\/h2>\n\n\n\n<p>When a <code>CHAR<\/code> column is not fully populated with a string of characters, the extra unused characters are padded with spaces. When a <code>CHAR<\/code> column is padding with spaces, it might cause some problems when concatenating <code>CHAR<\/code> columns together. To better understand this, here are a few examples that use the table created in Listing 6.<\/p>\n\n\n\n<p><strong>Listing 6: Sample Table<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE tempdb;\nGO\nCREATE TABLE Sample (\nID int identity,\nFirstNameChar CHAR(20),\nLastNameChar CHAR(20),\nFirstNameVarChar VARCHAR(20),\nLastNameVarChar VARCHAR(20));\nINSERT INTO Sample VALUES ('Greg', 'Larsen', 'Greg', 'Larsen');<\/pre>\n\n\n\n<p>The <em>Sample<\/em> table created in Listing 6 contains 4 columns. The first two columns are defined as <code>CHAR(20)<\/code> and the second two columns are defined as <code>VARCHAR(20)<\/code> columns. These columns will be used to store my first and last name.<\/p>\n\n\n\n<p>In order to demonstrate the concatenation problem associated with padded <code>CHAR<\/code> columns, run the code in Listing 7.<\/p>\n\n\n\n<p><strong>Listing 7: Showing concatenation problem<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT FirstNameChar + LastNameChar AS FullNameChar, \n       FirstNameVarChar + LastNameVarChar AS FullNameVarChar FROM Sample;<\/pre>\n\n\n\n<p>Report 1 contains the output when Listing 7 is executed<\/p>\n\n\n\n<p><strong>Report 1: Output when code in Listing 7 is run<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"206\" height=\"34\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/01\/word-image-8.png\" alt=\"Image showing what happens when CHAR datatype is used and there are extra spaces between the words.\" class=\"wp-image-93169\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In Report 1, the <code>FirstNameCHAR<\/code> column contains several spaces between my first and last name. These spaces came from the spaces that were padded onto the <code>FirstNameCHAR<\/code> column when it was stored in the <code>CHAR<\/code> column. The <code>FullNameVARCHAR<\/code> column does not contain any spaces between first and last name. No spaces are padded when column values are less than the length of the <code>VARCHAR<\/code> column.<\/p>\n\n\n\n<p>When concatenating <code>CHAR<\/code> columns, you might need to remove the trailing spaces to get the results you want. One method of eliminating the spaces can be done using the <code>RTRIM<\/code> function, as shown in Listing 8.<\/p>\n\n\n\n<p><strong>Listing 8: Removing trailing spaces using the RTRIM function<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT RTRIM(FirstNameChar) + RTRIM(LastNameChar) AS FullNameChar, \n       FirstNameVarChar + LastNameVarChar AS FullNameVarchar \nFROM Sample;<\/pre>\n\n\n\n<p>Output in Report 2 created when Listing 8 is executed is shown below.<\/p>\n\n\n\n<p><strong>Report 2: Output when Listing 8 is run<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"177\" height=\"42\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/01\/word-image-9.png\" alt=\"Image showing results when spaces are removed before concatenation GregLarsen GregLarsen\" class=\"wp-image-93170\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>By using the <code>RTRIM<\/code> function, all the additional spaces added to the <code>FirstNameCHAR<\/code> and the <code>LastNameCHAR<\/code> columns were removed before the concatenation operations were performed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-problems-searching-char-columns-for-spaces\">Problems searching CHAR columns for spaces<\/h2>\n\n\n\n<p>Because <code>CHAR<\/code> columns might be padded with spaces, searching for a space might be problematic.<\/p>\n\n\n\n<p>Suppose you have a table containing phrases, like the one created in Listing 9.<\/p>\n\n\n\n<p><strong>Listing 9: Creating <em>Phrase <\/em>table<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE tempdb;\nGO\nCREATE TABLE Phrase (PhraseChar CHAR(100));\nINSERT INTO Phrase VALUES ('Worry Less'),\n                          ('Oops'),\n                          ('Think Twice'),\n                          ('Smile');<\/pre>\n\n\n\n<p>Some phrases in table <em>Phrase <\/em>consist of just a single word, while the rest have two words. To search the <em>Phrase <\/em>table to find all the phrases that contain two words, the code in Listing 10 is used.<\/p>\n\n\n\n<p><strong>Listing 10: Trying to find two-word phrases<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT PhraseChar FROM Phrase WHERE PhraseChar like '% %';<\/pre>\n\n\n\n<p>The output in Report 3 is produced when Listing 10 is run.<\/p>\n\n\n\n<p><strong>Report 3: Output when Listing 10 is executed<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"66\" height=\"78\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/01\/text-description-automatically-generated-with-med.png\" alt=\"Text\n\nDescription automatically generated with medium confidence\" class=\"wp-image-93171\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Why did all the phrases in the <em>Phrase <\/em>table get returned when only two rows contained 2-word phrases? The search string <code>% %<\/code> also found the spaces that were padded to the end of the column values. Once again, the <code>RTRIM<\/code> can be used to make sure the spaces associated with the padding are not included in the search results by running the code in Listing 11.<\/p>\n\n\n\n<p><strong>Listing 11: Removing the trailing spaces<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT PhraseChar FROM Phrase\nWHERE RTRIM(PhraseChar) like '% %';<\/pre>\n\n\n\n<p>I\u2019ll leave it up to you to run the code in Listing 11 to verify if it only finds two-word phrases.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-performance-consideration-between-varchar-and-char\">Performance consideration between VARCHAR and CHAR<\/h2>\n\n\n\n<p>The amount of work the database engine has to perform to store and retrieve <code>VARCHAR<\/code> columns is more than it takes for a <code>CHAR<\/code> column. Every time a <code>VARCHAR<\/code> column is retrieved, the Database engine has to use the length information stored with the data to retrieve a VARCHAR column value. Using this length information takes extra CPU cycles. Whereas a <code>CHAR<\/code> column and its fixed length allow SQL Server to more easily chunk through <code>CHAR<\/code> column based on their fixed-length column definitions.<\/p>\n\n\n\n<p>Disk space is also an issue to consider when dealing with <code>CHAR<\/code> and <code>VARCHAR<\/code> columns. Because <code>CHAR<\/code> columns are fixed-length, they will always take up the same amount of disk space. <code>VARCHAR<\/code> columns vary in size, so the amount of space needed is based on the size of the strings being storeded instead of the size of the column definition. When a large majority of the values stored in a <code>CHAR<\/code> column are less than the defined size, then possibly using a <code>VARCHAR<\/code> column might actually use less disk space. When less disk space is used, less I\/O needs to retrieve and store the column value, which means better performance. For these two reasons, choose between <code>CHAR<\/code> and <code>VARCHAR<\/code> wisely based on the varying size of the string values being stored.<\/p>\n\n\n\n<p><strong>Read also:<\/strong> <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/beginner-guide-to-in-memory-optimized-tables-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">In-memory optimized tables in SQL Server<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-char-varchar-and-varchar-max\">CHAR, VARCHAR, and VARCHAR(MAX)<\/h2>\n\n\n\n<p>CHAR columns are fixed in size, while <code>VARCHAR<\/code> and <code>VARCHAR(MAX)<\/code> columns support variable-length data. CHAR columns should be used for columns that vary little in length. String values that vary significantly in length and are no longer than 8,000 bytes should be stored in a <code>VARCHAR<\/code> column. If you have huge strings (over 8,000 bytes), then <code>VARCHAR(MAX)<\/code> should be used. In order to store <code>VARCHAR<\/code> columns, the length information along with the data is stored. Calculating and storing the length value for a <code>VARCHAR<\/code> column means SQL Server has to do a little more work to store and retrieve <code>VARCHAR<\/code> columns over <code>CHAR<\/code> column data types.<\/p>\n\n\n\n<p>The next time you need to decide if a new column should be a <code>CHAR<\/code>, <code>VARCHAR<\/code>, or <code>VARCHAR(MAX) <\/code>column, ask yourself a few questions to determine the appropriate data type. Are all the string values to be stored close to the same size? If the answer is yes, then you should use a <code>CHAR<\/code>. If strings to be stored vary greatly in size, and values are all less than or equal to 8,000 bytes in size, then use <code>VARCHAR<\/code>. Otherwise, <code>VARCHAR(MAX) <\/code>should be used.<\/p>\n\n\n\n<p><em>If you liked this article, you might also like&nbsp;<\/em><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/sql-server-identity-column\/\"><em>SQL Server identity column.<\/em><\/a><\/p>\n\n\n\n<section id=\"my-first-block-block_d0169b026a13daf97abe81688f80aa78\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Fast, reliable and consistent SQL Server development&#8230;<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            &#8230;with SQL Toolbelt Essentials. 10 ingeniously simple tools for accelerating development, reducing risk, and standardizing workflows.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-toolbelt-essentials\/\" class=\"btn btn--secondary btn--lg\">Learn more &amp; try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: When to use CHAR, VARCHAR or VARCHAR(MAX) in SQL Server<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. What is the maximum length of VARCHAR and VARCHAR(MAX) in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>VARCHAR can store up to 8,000 bytes (characters for single-byte encodings). VARCHAR(MAX) can store up to 2^31 &#8211; 1 bytes (approximately 2 GB). For VARCHAR(MAX), values under 8,000 bytes are stored in-row by default; larger values are stored as LOB (Large Object) data with a pointer in the row, which has different performance characteristics for sorting and indexing.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. What is the difference between CHAR and VARCHAR in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>CHAR is a fixed-length data type that always uses the defined number of bytes, padding shorter values with trailing spaces. VARCHAR is variable-length and only uses the storage needed for the actual data plus 2 bytes of length overhead. CHAR is more efficient for columns where all values are the same length; VARCHAR is better when lengths vary, as it avoids wasting storage on padding.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. Does CHAR or VARCHAR perform better in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>For fixed-length data, CHAR can be marginally faster because SQL Server doesn\u2019t need to calculate variable lengths. For variable-length data, VARCHAR is better because it reduces I\/O by storing less data per row. In practice, the performance difference is usually negligible for most workloads &#8211; choose based on data characteristics rather than micro-optimization.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Compare CHAR, VARCHAR, and VARCHAR(MAX) in SQL Server &#8211; when to use each, storage differences, performance impact, and maximum length limits. Includes decision guide and examples.&hellip;<\/p>\n","protected":false},"author":78478,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,143525],"tags":[5134],"coauthors":[11330],"class_list":["post-93166","post","type-post","status-publish","format-standard","hentry","category-featured","category-learn","tag-sql-prompt"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/78478"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=93166"}],"version-history":[{"count":6,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93166\/revisions"}],"predecessor-version":[{"id":109049,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93166\/revisions\/109049"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=93166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=93166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=93166"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=93166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}