Insights into Company
← Spring Boot

Caching & Redis

01 What is Redis and where is it used in Spring Boot?

Solution and explanation

Solution:

Redis is commonly used for very fast temporary or frequently accessed data.

Examples:

  1. Job search cache.
  2. Company profile cache.
  3. Session storage.
  4. OTP expiration.
  5. Rate limiting.
  6. Counters.
  7. Distributed locks.
  8. Temporary tokens.

Example:

Suppose 100,000 users search:

"Laravel developer in Punjab"

Without caching, every request may execute database/search queries.

With Redis:

First request:

Redis MISS

v Database/Search

v Redis SET

Next requests:

Request

v Redis HIT

v Response

The database remains authoritative.

Do not treat Redis cache as the permanent source of truth unless the architecture explicitly requires Redis as a durable data store.

Run this example
        spring:
          data:
            redis:
              host: localhost
              port: 6379

          cache:
            type: redis

        @Cacheable(
            value = "companies",
            key = "#companyId"
        )
        public CompanyDto getCompany(Long companyId) {

            return companyRepository
                .findById(companyId)
                .map(companyMapper::toDto)
                .orElseThrow();
        }
Hands-on challenge

Cache a company profile for repeated requests and verify that the database is not queried on every request.

Quick check

Which statement is correct?

02 What is cache invalidation?

Solution and explanation

  • Solution:
  • Suppose:
  • Company 100
  • has:
  • employeeCount = 5000
  • The value is cached.
  • Redis:
  • company:100 -> employeeCount 5000
  • Now the database is updated:
  • employeeCount = 5200
  • If Redis still contains 5000, users receive stale data.
  • Therefore the application needs an invalidation strategy.
  • After updating:
  • Database -> 5200
  • Redis key deleted
  • Next read:
  • Redis MISS
  • Database -> 5200
  • Redis -> cache 5200
  • For frequently changing data, use a shorter TTL or event-driven invalidation.
  • Never assume that adding a cache automatically makes an application correct.
Run this example
        @CacheEvict(
            value = "companies",
            key = "#companyId"
        )
        @Transactional
        public CompanyDto updateCompany(
                Long companyId,
                UpdateCompanyRequest request
        ) {

            Company company =
                companyRepository
                    .findById(companyId)
                    .orElseThrow();

            company.setName(request.name());
            company.setEmployeeCount(
                request.employeeCount()
            );

            Company saved =
                companyRepository.save(company);

            return mapper.toDto(saved);
        }
Hands-on challenge

Update a company and verify that the next GET reads the new database value.

Quick check

Which statement is correct?