LINQ (Language Integrated Query) is a powerful feature in .NET that allows developers to query and manipulate data in a consistent, declarative way using C# (or other .NET languages). LINQ enables querying of various data sources such as arrays, collections, databases, XML, and more, directly within the programming language.
With its syntax closely integrated into C#, LINQ allows developers to write queries as part of their code, making it easier to express complex data operations such as filtering, sorting, and grouping. LINQ’s ability to work with diverse data sources while maintaining readability and type safety is one of the key reasons for its popularity in .NET development.
While LINQ makes writing queries concise and readable, it’s important to be mindful of its impact on performance and scalability — especially when dealing with large datasets or complex queries. This article will explore best practices and advanced strategies to optimize LINQ queries, improving the performance and scalability of your .NET applications.
1️⃣Use IQueryable Instead of IEnumerable for Database Queries
The choice between IQueryable and IEnumerable can significantly impact the performance of your queries. IQueryable enables deferred execution, meaning the query is not executed until the results are actually needed. This also allows LINQ queries to be translated into optimized SQL queries by the database engine, which can apply its own optimizations to retrieve the data more efficiently. This is especially beneficial when dealing with large datasets or complex queries.
In contrast, IEnumerable executes the query in-memory, immediately fetching and processing all data. While convenient for smaller data sets, this approach can be inefficient and resource-intensive when working with large amounts of data, as it does not take advantage of database-level optimizations.
// Using IQueryable for database queries to enable optimized SQL execution IQueryable<Product> products = dbContext.Products.Where(p => p.Price > 50);
In the code example, IQueryable<Product> is used to query the Products table for items with a price greater than 50. The Where() clause applies filtering, but the query is not executed at this point. Since IQueryable is being used, the query remains open and can be further modified or combined with other query operators before execution. This allows the SQL generation process to be deferred until the query is actually executed, enabling SQL optimizations by the database engine for performance. By using IQueryable instead of IEnumerable, the execution is more efficient as it avoids pulling all data into memory before filtering.
2️⃣Minimize Round Trips to the Database
Each time a LINQ query triggers a call to the database, it can result in a round trip, which introduces latency and can severely impact performance, especially when multiple database calls are involved. To optimize query efficiency, it’s crucial to minimize these round trips. Whenever possible, try to perform filtering, sorting, and projection (transforming or shaping the data) directly within the query itself. By pushing these operations to the database, you reduce the need for additional queries and ensure that only the necessary data is retrieved, improving both performance and scalability.
// Fetching only necessary data in a single query var highValueProducts = dbContext.Products .Where(p => p.Price > 50) .Select(p => new { p.Name, p.Price }) .ToList();
In this example, the Where() clause filters the products based on a Price greater than 50, and then the Select() method is used to return only the Name and Price fields of the matching products. This prevents the retrieval of unnecessary data from the database, improving performance by reducing the size of the result set. Instead of returning the entire Product entity, the query is optimized by fetching only the specific fields that are required for further processing. The result is then materialized into a list using ToList(). This ensures that the application works more efficiently by minimizing the data load and memory consumption.
3️⃣Avoid Using .ToList() or .ToArray() Early
Calling .ToList() or .ToArray() in a LINQ query triggers immediate execution, causing all the data to be pulled into memory at once. This can lead to unnecessary memory usage and performance bottlenecks, particularly when dealing with large datasets. Instead of forcing immediate execution, it’s more efficient to let the query execute lazily, meaning the query is only evaluated when the data is actually needed. This deferred execution allows you to process data on demand, reducing memory consumption and improving overall performance until the query results are required.
// Delay execution until necessary to fetch data var products = dbContext.Products.Where(p => p.InStock).Take(10);
In the example, the LINQ query defines conditions using Where() to filter for products that are in stock and limits the result to 10 items using Take(10). However, no data is retrieved at this point because the query hasn’t been executed yet. This is due to deferred execution—the query is not run until the results are actually needed. This means the query can be combined or modified further before execution, and the database can optimize the final SQL query, ensuring efficient data retrieval. This deferred approach also helps in scenarios where only a portion of the data may be needed, improving both performance and resource usage.
4️⃣Optimize Complex LINQ Queries
Complex LINQ queries can sometimes lead to inefficient SQL generation, which can negatively impact performance. When LINQ queries become large and intricate, they may result in poorly optimized SQL that places unnecessary load on the database. To improve performance, consider breaking down large queries into smaller, more manageable parts. Additionally, using explicit joins instead of more complex operations like group joins or SelectMany can help streamline the query execution. Simplifying your LINQ queries ensures more efficient SQL generation, allowing the database engine to execute them faster and with fewer resources.
// Simplified version of a complex query var orderDetails = dbContext.Orders .Where(o => o.Date > startDate) .Join(dbContext.Customers, order => order.CustomerId, customer => customer.CustomerId, (order, customer) => new { order.OrderId, customer.Name }) .ToList();
This code example optimizes LINQ query performance by breaking down a complex query into smaller, more efficient components. Here’s how it accomplishes that:
Filtering with Where(): The query first applies a filter with .Where(o => o.Date > startDate). This reduces the dataset early on, ensuring that only the relevant orders are considered, thus minimizing unnecessary data processing.
Using Explicit Join(): Instead of using a more complex operation like GroupJoin or SelectMany, the query uses an explicit Join to combine data from the Orders and Customers tables. This approach results in more efficient SQL generation because it directly defines how the two tables should be joined, which is often easier for the database engine to optimize.
Projection with new {}: The query uses a projection (new { order.OrderId, customer.Name }) to select only the necessary data — in this case, the OrderId and Name — rather than fetching all columns from both tables. This reduces the amount of data transferred from the database to the application, improving performance.
Immediate Execution with .ToList(): Finally, .ToList() triggers immediate execution of the query, pulling the filtered, joined, and projected data into memory for further use.
By using an explicit Join and reducing the dataset early with Where() and new {}, this query avoids the inefficiencies of complex operations like GroupJoin or SelectMany and ensures the SQL generated is optimized for performance.
5️⃣Use Select for Projection Instead of Returning Entire Entities
When querying large datasets, it’s essential to return only the fields you actually need. One effective way to do this is by projecting the data into a simpler type, such as an anonymous type or a Data Transfer Object (DTO). This practice reduces memory usage by limiting the amount of data retrieved from the database and processed in memory, leading to improved performance. By selecting only the necessary fields, you can significantly optimize query execution, especially when dealing with large tables or complex queries.
// Returning only the needed data (Name, Price) to minimize memory usage var products = dbContext.Products .Where(p => p.Price > 50) .Select(p => new { p.Name, p.Price }) .ToList();
In the provided code example, the LINQ query efficiently limits the data returned by projecting only the Name and Price fields from the Products table. The Where clause filters products where the Price is greater than 50, narrowing the dataset right from the start. Then, the Select operator is used to create a new anonymous type containing just the Name and Price properties. This ensures that only the essential data is fetched and transferred, minimizing memory consumption and enhancing query performance. The .ToList() method forces the query to execute immediately, retrieving only the required data into memory.
6️⃣Avoid N+1 Query Problem
The N+1 query problem arises when a query retrieves a collection of entities, and then for each entity in the collection, a separate query is issued to retrieve related data. This leads to multiple database queries — often one query for the main data and additional queries for each related entity — resulting in unnecessary database load and performance degradation. To mitigate this, eager loading can be employed, where related entities are loaded in a single query alongside the main data. By using methods like Include(), you can load related entities all at once, reducing the number of database round trips and significantly improving query performance.
// Using Include to eagerly load related entities and avoid N+1 queries var orders = dbContext.Orders .Include(o => o.Customer) .Where(o => o.Status == "Pending") .ToList();
In the provided code example, the query uses .Include(o => o.Customer) to eagerly load the Customer related to each Order in the Orders collection. Instead of issuing separate queries for each order’s associated customer, the Include() method ensures that both the orders and their related customers are retrieved in a single query. This approach prevents the N+1 query problem by minimizing the number of database calls. The query further filters the orders by Status == "Pending" and uses .ToList() to execute the query and fetch the results efficiently.
7️⃣Use Skip and Take for Paging Instead of Loading All Data
When dealing with large datasets, loading all the data into memory can lead to performance issues and unnecessary memory consumption. To efficiently handle cases where only a subset of the data is needed — such as when implementing paging — Skip() and Take() can be used. These methods allow you to retrieve only a specific portion of the data, avoiding the overhead of loading large amounts of information at once. Skip() skips a specified number of records based on the current page index, while Take() limits the number of records retrieved to the page size. This approach ensures that only the required data is fetched, making it more efficient and scalable for scenarios like paging.
// Implementing paging with Skip and Take var pagedProducts = dbContext.Products .OrderBy(p => p.Name) .Skip(pageIndex * pageSize) .Take(pageSize) .ToList();
In the provided code example, the query uses Skip(pageIndex * pageSize) to skip over the records of previous pages and Take(pageSize) to fetch only the specified number of products for the current page. The products are first ordered by their Name to ensure a consistent and predictable result set. By using these methods, the query only loads a subset of the Products data into memory at a time, based on the current page. This approach helps to minimize the memory footprint and ensures that only the necessary data is fetched from the database, improving performance when implementing paging.
8️⃣Use AsNoTracking() for Read-Only Queries
When querying data for read-only operations where no modifications are intended, change tracking can introduce unnecessary overhead in Entity Framework. Entity Framework tracks changes to entities so it can detect and persist modifications to the database. However, if you’re only retrieving data for display or other non-modifying purposes, this tracking process can be avoided. By using the AsNoTracking() method, you can improve query performance, as it tells Entity Framework not to track changes for the queried entities. This results in faster query execution and reduced memory usage, especially when dealing with large datasets.
// Using AsNoTracking() for read-only queries to improve performance var products = dbContext.Products.AsNoTracking() .Where(p => p.Category == "Electronics") .ToList();
In the provided code example, the AsNoTracking() method is applied to the Products query to disable change tracking for the retrieved Products entities. This is particularly useful when the data is only being read and no updates will be made. The query retrieves products that belong to the “Electronics” category and executes the query with ToList() to fetch the results. By bypassing change tracking, the query becomes more efficient, reducing memory usage and speeding up performance, particularly in scenarios where many read-only queries are executed.
9️⃣Use FirstOrDefault or SingleOrDefault Instead of Where When You Expect a Single Result
When querying for a single result, using methods like FirstOrDefault() or SingleOrDefault() is more efficient than using Where(). The Where() method returns a collection, even if only one item matches the query, which is unnecessary when you’re expecting a single entity. In contrast, FirstOrDefault() retrieves the first matching result or returns null if no match is found, while SingleOrDefault() assumes there is either one or no result and throws an exception if multiple results are found. By using these methods, you avoid the overhead of materializing an entire collection, leading to better performance and more concise code.
// Using FirstOrDefault for a single result instead of Where var product = dbContext.Products .FirstOrDefault(p => p.Name == "Laptop");
In the provided code example, FirstOrDefault() is used to query for a Product whose Name is “Laptop.” Since the expectation is to retrieve a single product (or null if no such product exists), FirstOrDefault() is a more efficient choice compared to Where(), which would return a collection. By using FirstOrDefault(), the query directly returns the first matching result without needing to build a collection, improving both performance and clarity in the code.
Optimizing LINQ queries is crucial for improving the performance and scalability of your .NET applications, especially as data grows. By following best practices like using IQueryable, minimizing database round trips, projecting only necessary data, and avoiding common pitfalls like N+1 queries, you can significantly enhance the speed and efficiency of your queries. Additionally, adopting strategies like paging, eager loading, and using AsNoTracking() for read-only queries can further optimize performance. With these tips, your LINQ queries will be more efficient, scalable, and ready for even the most demanding applications.
{"id":"2","mode":"button","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":false,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"robhutton.com","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"robhutton.com","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"robhutton.com","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}
{"id":"4","mode":"text_link","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Like my articles? Tips are appreciated.","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}