Customers Contact TR

Best Practices for Looker Development: A Practical Guide for Data Teams

When building and maintaining Looker projects, the difference between a smooth, scalable setup and a tangled mess often comes down to following the right practices from day one. Whether you are a Looker developer or part of a data engineering team, applying these best practices can help you avoid costly mistakes, keep your code maintainable, and deliver consistent, reliable insights.


Below, we will cover six critical areas: LookML Project & Git Integration, Dimension & Measure Modeling, Code Organization & Readability, Explore Modeling & Joins, Derived Tables, and Caching & Datagroups.


💡 To check our previous blogs about Looker, click here.


1. LookML Project & Git Integration

Looker’s Git integration is more than just a convenience; it is the backbone of version control and collaboration in LookML projects. Here is how to make the most of it:


  • One project = one Git repo
    Maintain a one-to-one mapping between your LookML project and its dedicated Git repository. This makes version control simpler and reduces merge conflicts.


💡 LookML Project: A LookML project is the collection of LookML files (views, models, dashboards, etc.) that define your Looker environment. It is essentially the codebase for your Looker data model.


💡 Git Repository: A Git repository is where your LookML project’s code is stored and versioned. In Looker, this enables collaboration, rollback, and proper version control.



  • Always pull before you push
    In Development Mode, pull the latest changes from production before editing. This ensures you are working with the most up-to-date version of all files.


💡 Development Mode: A personal workspace in Looker where you can safely make and test changes to LookML without affecting the production environment.



  • Write meaningful commit messages
    A short comment explaining your changes can save hours of confusion later. Be clear and descriptive.

  • Review before deploying
    Test your changes in Explore before pushing them to production. This helps catch errors early.


💡 Explore: An Explore is the user-facing interface in Looker where you can query data based on your LookML models. It is also where you validate your development changes before deploying.



  • Run Project Health checks
    Always run Looker’s Project Health tests before deployment to avoid broken content or performance issues.


💡 Project Health Tests: Built-in Looker validations that scan your LookML for common issues such as syntax errors, broken references, or missing fields.



2. Dimension & Measure Modeling

Modeling is where LookML’s flexibility shines, but it is also where inconsistent naming, hard-coded logic, or poor structuring can lead to future headaches. Follow these practices to keep your modeling clean and scalable:


  • Use ${field_name}, not ${TABLE}
    When building new dimensions based on existing ones, reference them with ${field_name}. This avoids hard-coded column names and ensures your new fields inherit any transformations or logic.

Example:


dimension: full_name{
     sql: concat(${first_name}, " ", ${last_name}) ;;
     }



💡 ${field_name}: References another field in the same LookML model, inheriting its logic or transformations.


💡 ${TABLE}: References the base SQL table for the view. This can lead to hard-coded logic if used instead of ${field_name}.



  • Avoid redundant names in time dimensions
    For dimension_group: type: time, do not add “date” or “time” in the name. Keep it clean.


💡 Dimension Group: A set of related fields (dimensions) generated from a single column, such as multiple time intervals (day, week, month) created from a date field.



  • Use duration dimension groups
    Instead of manually calculating date differences in sql, create type: duration dimension groups. This gives business users flexible time intervals and adapts better if the source changes.

  • Follow a consistent naming convention
    Use lowercase letters and underscores for field names (full_name, total_sales). LookML is case-sensitive, so consistency matters.

  • Keep the semicolons
    Always leave the two ;; at the end of SQL expressions inside the sql parameter. This signals where the SQL ends.

  • Validate as you build
    Keep one Explore tab open in Development Mode. After each change, refresh to quickly confirm it works as expected.

3. Code Organization & Readability

Keeping your LookML code clean and organized makes it easier for your team to maintain and scale.


  • Order fields logically
    While not strictly enforced, place new dimensions or measures after existing ones in the view file to keep related fields together.

  • Use clear dashboard filenames
    Follow the convention name.dashboard.lookml for LookML dashboard files. This helps with quick identification and consistency.

4. Explore Modeling & Joins

Explores are the heart of Looker, and getting their structure right impacts both performance and usability.


  • Prefer direct joins from the base view
    Use a join key from the base view when possible to avoid the performance costs of indirect joins.

  • Always define a primary key
    Set primary_key: yes in every view, even if it is not currently being joined in an Explore. This enables symmetric aggregation.


💡 primary_key: A property in LookML that identifies the unique row identifier in a view. This enables features like symmetric aggregation, which ensures consistent query results across joins.


💡 Symmetric Aggregation: A Looker optimization that ensures measures aggregate correctly even when joined views have different levels of granularity.



  • Specify relationships correctly
    For every join, set the relationship parameter accurately to ensure correct aggregation results.


💡 relationship Parameter: Defines how a join should behave in an Explore (one_to_one, many_to_one, one_to_many, many_to_many). Incorrect settings can cause inaccurate aggregation.



5. Derived Tables

Derived tables can be powerful, but they require disciplined setup to avoid future headaches.


For SQL Derived Tables (via SQL Runner):

  • Move the new view file to the views folder.
  • Remove any LIMIT clauses used for testing.
  • Hide unnecessary auto-generated count measures or remove them entirely.
  • Define a primary_key for the view (e.g., primary_key: yes for order_id in order_facts).


💡 SQL Derived Table (SDT): A view in Looker created from custom SQL queries instead of a physical table in your database.



For Native Derived Tables (NDTs):

  • Create a new view for each NDT.
  • Move the new view file to the views folder.
  • Rename the auto-generated view name to match the view file name.
  • Leave the model file reference commented out to prevent circular dependencies.


💡 Native Derived Table (NDT): A view in Looker created directly in LookML using derived_table parameters, without writing raw SQL.



For Persistent Derived Tables (PDTs):

  • Use a dedicated schema in your database for PDTs (e.g., X_scratch).
  • Prefer datagroup_trigger if datagroups are already defined.
  • If using persist_for, pair it with sql_trigger_value or use either on its own for data freshness.
  • For cascading PDTs with the same datagroup_trigger, Looker will handle dependency order automatically.
  • Add indexing to PDTs for faster query performance.


💡 Persistent Derived Table (PDT): A derived table stored in your database for faster queries. PDTs can be refreshed on a schedule or triggered by datagroups.



6. Caching & Datagroups

Caching is essential for performance, and datagroups are the key to controlling it effectively.


  • Use both parameters in datagroups
    Define both max_cache_age and sql_trigger for reliable caching with a fallback mechanism.


💡 max_cache_age: A datagroup parameter that sets the maximum time. Looker should keep cached query results before refreshing.


💡 sql_trigger: A datagroup parameter that runs a SQL query to check if new data is available, triggering a cache refresh if the result changes.



  • Link PDTs to datagroups
    Apply the datagroup_trigger parameter to PDTs to keep data up to date.


💡 datagroup_trigger: A parameter in LookML that ties a PDT’s refresh schedule to a specific datagroup’s settings.



  • Know the limits with dynamic usernames
    If your connection uses dynamic usernames (e.g., BigQuery OAuth), datagroups and PDTs are not supported. In this case, use persist_for to cache Explore queries for a set duration.

Business Use Case: Building a Regional Sales Performance Dashboard in Looker



The Scenario: Your company operates in multiple countries, and the sales leadership team wants a Regional Sales Performance Dashboard in Looker. This dashboard should allow managers to:

  • View total sales and average order value by region.
  • Compare performance month-over-month.
  • Drill down to specific product categories.
  • Refresh data daily from the company’s cloud data warehouse.

The data model will combine three main sources:

  1. Orders (transaction-level data)
  2. Customers (customer profiles)
  3. Products (product catalog and categories)



How to Approach It


1. Set up the LookML Project and Git Integration

  • Create a dedicated LookML project for this dashboard, mapped to its own Git repository.
  • Always pull from production before starting work to avoid overwriting changes made by other developers.

2. Model the Views and Explores

  • In the Orders view, define primary_key: yes on order_id to ensure symmetric aggregation.
  • Use ${field_name} references when building derived fields like full_name for customers to avoid hard-coded SQL.
  • For date fields like order_date, create a dimension group of type: time (e.g., day, week, month) so business users can flexibly group results.

3. Join the Data

  • In the Explore, join the Customers and Products views directly from Orders (the base view) instead of chaining joins through another table. This improves performance.
  • Set the relationship parameter correctly (e.g., many_to_one for Orders → Customers).

4. Optimize with Derived Tables

  • Use a Persistent Derived Table (PDT) to pre-aggregate monthly sales totals by region.
  • Tie the PDT refresh to a datagroup_trigger that checks for new data daily using both max_cache_age and sql_trigger for reliable refreshes.
  • Place the PDT in a dedicated schema in your database.

5. Build the Dashboard

  • Name the file using the best practice format: regional_sales_performance.dashboard.lookml.
  • Keep the measures and dimensions logically grouped in the view files so the next developer can easily find them.

6. Test and Deploy

  • Keep an Explore tab open in Development Mode to validate fields as you create them.
  • Run Project Health tests to catch any broken references or missing fields.
  • Review results in Explore before deploying to production.


⭐⭐⭐


Looker is a powerful platform, but its true potential comes from disciplined, consistent development practices. From Git integration and field modeling to Explore joins, derived tables, and caching strategies, every best practice you follow adds up to a cleaner, faster, and more scalable analytics environment. By standardizing these approaches, your team can work more efficiently, reduce errors, and deliver insights your business can trust, today and as your data needs evolve.


If you are ready to take your Looker development to the next level, contact us today. We will help you implement these best practices and build an analytics foundation that grows with your business.


Author: Umniyah Abbood

Date Published: Aug 19, 2025



Discover more from Kartaca

Subscribe now to keep reading and get access to the full archive.

Continue reading