Category Image

Mobile Dev

From Expense to Efficiency: Making App Servers 421 Times More Cost-Effective for one of Finland’s biggest student events

December 12, 2023
From Expense to Efficiency: Making App Servers 421 Times More Cost-Effective for one of Finland’s biggest student events

From Expense to Efficiency: Making App Servers 421 Times More Cost-Effective for one Finland’s biggest student events

Recently, our company took on the exciting challenge of developing the mobile application for Glöggrundan, one of Finland's largest student events. With approximately 5500 enthusiastic attendees which 3200 of them downloaded the app, the stakes were high. The app was designed to enhance the overall experience, offering a countdown to the event, real-time updates, an interactive map showcasing the 69 pub crawl locations, event schedules, and general information. Additionally, a dedicated page allowed users to delve deeper into details about each pub crawl venue.

Recognizing the potential scalability challenges and associated costs, especially given the multitude of images involved (69 venues with up to 5500 potential downloads), we implemented strategic optimizations. For instance, we addressed the issue of image sizes, a crucial factor impacting data transfer and associated expenses.

Given the potential for up to 5500 app downloads and 69 pub crawl locations, cost efficiency became a priority. If each image were 1mb and were accessed six times per user, the data transfer could reach 2277 GB, costing 248 € (Without taxes) via Firebase, or 143 € (Without taxes) for 3200 downloads. 

Initially, we tackled image compression. Realizing that users wouldn't necessarily discern lower resolution on their mobile devices, we opted to upload photos with reduced quality. The subsequent step involved further compressing the images and converting them from PNG to JPG format. This change not only optimized storage but also significantly decreased file sizes. The images, initially around 1 MB each, were successfully reduced to a mere 18 KB on average after the compression and format conversion, resulting in a total of 1.59 MB for all pictures.

To further minimize data usage, we implemented a smart solution. Recognizing that the images for the various pub crawl locations remained relatively static, we developed a function that efficiently managed image downloads. This function checked the storage with the image link as a key, only downloading the image if it hadn't been previously cached. Consequently, users now downloaded all the images just once, significantly reducing the load on resources.

  Future<Uint8List?> getNetworkImage() async {
    if (logo_path != "") {
      final directory = await getApplicationDocumentsDirectory();
      final path = File('${directory.path}/$logo_path');
      if (await path.exists()) {
        Uint8List bytes = path.readAsBytesSync();
        return bytes;
      } else {
        var dio = Dio();
        Uint8List? imageFile = await FirebaseStorage.instance.ref('logo_image').child(logo_path!).getData();
        String? imageFileURL = await FirebaseStorage.instance.ref('logo_image').child(logo_path!).getDownloadURL();
        await dio.download(imageFileURL, path.path);
        return imageFile;
      }
    }
    return null;
  }

Upon opening the app, a function was called to retrieve data from Firebase Firestore, including the links to the images. This approach ensured that users obtained up-to-date information without unnecessary image downloads, contributing to a more streamlined and cost-effective user experience.

In the widget displaying each venue along with its image and relevant information, we implemented the following code to seamlessly integrate these optimizations:

@override
  void initState() {
    super.initState();
    getImage();
  }

  void getImage() async {
    final GloggProvider gloggProvider = Provider.of<GloggProvider>(context, listen: false);

    if (widget.barData.file == null) {
      Uint8List? file;
      file = await widget.barData.getNetworkImage();
      gloggProvider.changeBarImageFile(file!, widget.barIndex);
    }
  }

To streamline the image loading process within the widget, I initiated the initState on the widget, seamlessly triggering the execution of the getImage function. Leveraging a provider that stored essential data regarding the diverse event locations, I invoked the getNetworkImage function, seamlessly updating the provider with the pertinent image file.

Upon the event's conclusion, we received the billing statement from Google, revealing a remarkably minimal cost of 0.42€, taxes included. This starkly contrasted with the initial projection of 143€ (excluding taxes) or 177€ (with taxes) (with 3300 downloads) before implementing our optimization measures.

While 0.42€ may seem inconsequential on its own, the true significance lies in the substantial reduction from the originally anticipated cost. In the context of a larger-scale project, these optimizations underscore their crucial role in efficiently managing expenses. This cost-effective approach not only exemplifies our commitment to meticulous planning and execution but also underscores the potential financial impact on more extensive endeavors, making such optimizations pivotal in the grand scheme of project management.

Share