Eliminate ImageKit Dependency For Cost Savings

Alex Johnson
-
Eliminate ImageKit Dependency For Cost Savings

In the fast-paced world of web development, efficiency and cost-effectiveness are paramount. As our platform, Eventasaurus, continues to evolve, we're always looking for ways to streamline our infrastructure and reduce unnecessary expenses. One significant step we're taking is to completely remove the ImageKit dependency. This move is particularly exciting because venue images are now seamlessly served from R2/Cloudflare. This means ImageKit is only being used for a few specific, yet removable, tasks: CDN transformations on Unsplash city fallback images and some event source images. By phasing out ImageKit, we anticipate substantial cost savings, allowing us to reinvest in other critical areas of development and user experience.

Understanding the Current ImageKit Usage

Before we dive into the solution, it's crucial to understand precisely how ImageKit is currently integrated into our system. The primary module affected is lib/eventasaurus/imagekit.ex. This module acts as the central hub for our ImageKit interactions. Beyond this core module, we find ImageKit being utilized in two key areas:

  1. City Fallback Image CDN: In lib/eventasaurus_discovery/public_events_enhanced.ex (line 973) and lib/eventasaurus_app/cache/city_fallback_image_cache.ex (line 246), ImageKit is employed to serve as a Content Delivery Network (CDN) for fallback city images. These are the images that appear when a specific event or venue doesn't have a unique image associated with it. ImageKit's role here is to resize and optimize these images, ensuring they load quickly and efficiently across different devices and network conditions.

What ImageKit Does Currently:

The transformation process is quite straightforward. ImageKit takes a URL, typically pointing to an image on Unsplash, and wraps it with its CDN service for resizing and optimization. For example, an original Unsplash URL like https://images.unsplash.com/photo-xxx would be transformed into something like https://ik.imagekit.io/wombie/https://images.unsplash.com/photo-xxx?tr=w-800,q-85. The ?tr=w-800,q-85 part indicates that the image should be resized to a width of 800 pixels and have a quality setting of 85. This optimization is beneficial for performance, but with the advent of more integrated solutions, it's becoming redundant.

This detailed breakdown confirms that our reliance on ImageKit is limited, making its removal a feasible and logical next step. The parent issue, #2977 (Venue Migration - Complete ✅), and the related issue #2915 (External Image Caching to R2) highlight the ongoing efforts to consolidate our image hosting and CDN strategies, of which removing ImageKit is a natural extension.

The Solution: Embracing Cloudflare Image Resizing

To completely remove the ImageKit dependency, our strategy is to leverage a solution we're already invested in and successfully using: Cloudflare Image Resizing. This powerful feature is part of Cloudflare's robust content delivery network and offers the same, if not better, performance and optimization capabilities that ImageKit provided, but without the additional cost and complexity of a separate service. Since we're already utilizing Cloudflare for R2-hosted images, integrating its image resizing capabilities for our remaining external image needs is a seamless and logical progression. This approach not only simplifies our architecture but also consolidates our CDN and image optimization efforts under a single, cost-effective provider.

Cloudflare Image Resizing Format:

Instead of relying on ImageKit's specific URL structure, we will adopt Cloudflare's standardized format. The transformation will look like this:

https://cdn.wombie.com/cdn-cgi/image/width=800,quality=85/{original-url}

Here's a breakdown of what this means:

  • https://cdn.wombie.com/: This is our primary Cloudflare CDN domain.
  • /cdn-cgi/image/: This specific path tells Cloudflare to apply its image optimization and resizing transformations.
  • width=800,quality=85: These are the parameters for the transformation, mirroring the functionality previously handled by ImageKit. We can adjust width and quality as needed, just as we did before.
  • {original-url}: This is the placeholder for the actual URL of the image you want to transform. This could be an Unsplash URL or any other external image source.

By adopting this Cloudflare-centric approach, we ensure that all image transformations are handled efficiently and consistently through our existing Cloudflare infrastructure. This eliminates the need for ImageKit, streamlines our codebase, and directly contributes to our goal of reducing operational costs. The integration is designed to be a direct replacement, minimizing disruption and maximizing the benefits of our current cloud services. This move aligns perfectly with our broader strategy of consolidating services and optimizing resource utilization.

Phased Implementation for Seamless Removal

To ensure a smooth transition and minimize any potential disruptions, we've broken down the process of removing the ImageKit dependency into manageable phases. Each phase has a clearly defined goal and estimated effort, allowing us to track progress effectively and address any issues as they arise. This structured approach is key to a successful infrastructure cleanup.

Phase 1: Create Cloudflare CDN Helper

Estimated effort: 0.5 day

The first critical step is to establish a robust and reusable way to apply Cloudflare's image transformations across our application. This involves creating a dedicated module, tentatively named Eventasaurus.Cdn, or enhancing an existing one if applicable.

1.1 Create Eventasaurus.Cdn module: We’ll implement a function, likely named transform, that takes an image URL and a set of options (like width and quality) and returns the Cloudflare-transformed URL. The basic structure would look something like this:

defmodule Eventasaurus.Cdn do
  @doc """
  Apply Cloudflare Image Resizing to any image URL.
  Works with both R2 URLs and external URLs.
  """
  def transform(url, opts \ [])
  
def transform(nil, _opts), do: nil
def transform("", _opts), do: ""
  
def transform(url, opts) when is_binary(url) do
    width = Keyword.get(opts, :width, 800)
    quality = Keyword.get(opts, :quality, 85)
    
    "https://cdn.wombie.com/cdn-cgi/image/width=#{width},quality=#{quality}/#{url}"
  end
end

This initial implementation will handle the core transformation logic. It's designed to be flexible, accepting optional parameters for width and quality, with sensible defaults.

1.2 Handle edge cases: Beyond the basic transformation, we need to make this helper resilient. This includes:

  • Skipping transformation if URL is already a CDN URL: We don't want to double-wrap URLs.
  • Skipping if URL is nil/empty: Gracefully handle missing or empty URLs.
  • Validating URL format: Ensure we're only attempting to transform valid image URLs.

This phase lays the groundwork for all subsequent replacements, ensuring a centralized and reliable method for image transformations.

Phase 2: Replace ImageKit Usage

Estimated effort: 0.5 day

With our new Eventasaurus.Cdn helper ready, the next phase involves systematically replacing all instances where ImageKit is currently used. This is a direct find-and-replace operation, ensuring consistency across the codebase.

2.1 Update public_events_enhanced.ex: We'll locate the specific lines where Eventasaurus.ImageKit.url is called and replace it with our new Eventasaurus.Cdn.transform function.

  • Before:
    Eventasaurus.ImageKit.url(url, width: 800, quality: 85)
    
  • After:
    Eventasaurus.Cdn.transform(url, width: 800, quality: 85)
    

2.2 Update city_fallback_image_cache.ex: This follows the exact same pattern as the update in public_events_enhanced.ex. We'll perform the direct replacement of the ImageKit function call with our Cloudflare CDN transformation.

2.3 Search for any other ImageKit references: To ensure we haven't missed anything, we'll use a comprehensive search command like `grep -r

You may also like