Skip to content


How-to Guides

Technical References

VIP File System /

Access to media uploads

The VIP Platform stores all uploaded media in a globally distributed object store called the VIP File System. This is seamlessly integrated with your WordPress application and all common operation including uploads, cropping, editing, and deletes work as expected.

All images uploaded to the VIP File System can make use of the Photon API, which allows for dynamic resizing and other manipulation (cropping, letterboxing, filters, etc.). Because image sizes all are created on-the-fly, uploads are significantly faster and changes to image sizes is much easier (no need to run scripts to regenerate files).

Note that files uploaded since 00:00 UTC 12 August 2020 are now treated as case-sensitive.

Programmatic access to media uploads

For programmatic access to media stored in the VIP File System, such as uploading and modifying files, you can use several different APIs.

For simple file uploads, the media_handle_sideload, media_sideload_image, or wp_upload_bits functions are very easy to work with.

For more complex interactions, we’ve integrated a custom PHP Stream Wrapper, which allows most filesystem functions (e.g. fopen, fwrite, file_put_contents, etc.) to work with media uploads. This means that most plugins that interact with media uploads will work on the VIP Platform without any modifications. There are some caveats

A few caveats to be aware of:

  • This only works for the uploads directory (i.e. paths that begin with /wp-content/uploads/; other paths will not work).
  • We default to a year/month directory structure for media uploads. This can be overridden by adding the following filter to your theme’s functions.php file:
add_filter( 'pre_option_uploads_use_yearmonth_folders', function() {return '0';}, 9999 );
  • You must use the WordPress function wp_get_upload_dir() or wp_upload_dir() to generate the correct, writeable path (hard-coding a path like /wp-content/uploads/... will not work).
  • Currently, not all filesystem functions and operations are supported (e.g. directory traversal).
  • Not all use cases are ideal or supported (e.g. files with high volumes of updates, such as logging).
  • Because communication with the VIP File System happens over HTTP, high number of function calls (e.g. lots of file_exists checks) can result in a performance hit and should be used with caution.
  • file_exists will always return true for extension-free values (e.g. directory names).
  • Only 2000 modifications of any particular file path are permitted. Modifications above this limit will result in an error being thrown with status 405. So plugins or features using the same filename (e.g. as part of a logging solution) will need to consider this limit.
  • To replace a media upload, you’ll need to directly overwrite a file by name (replace it); if the Media Uploader is used, it will typically see the same file and instead of replacing it, create a new file with a version tacked on to the end.
  • All files have a very long cache-control header, because they are typically not frequently modified. In order to ensure file requests obtain the latest version, files that are replaced may need to be explicitly purged from edge cache after replacement.
  • Using the WP_Filesystem API requires a specific snippet to work:
	global $wp_filesystem;
	if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base') ) {
		$creds = request_filesystem_credentials( site_url() );
		wp_filesystem( $creds );


Here’s a simple example of how to upload a file using PHP functions:

$csv_content = '1,hello,admin';

$upload_dir = wp_get_upload_dir()['basedir'];

$file_path = $upload_dir . '/csv/updated.csv';

file_put_contents( $file_path, $csv_content );

// The file will now be accessible at <a href=""></a>

Same as above, but using the WP_Filesystem API:

	$csv_content = '1,hello,admin';
	$upload_dir = wp_get_upload_dir()['basedir'];
	$file_path = $upload_dir . '/csv/updated.csv';

	global $wp_filesystem;
	if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base') ) {
		$creds = request_filesystem_credentials( site_url() );
		wp_filesystem( $creds );

Here’s an example that parses an uploaded CSV and stores the contents in a variable:

$csv_attachment = get_attached_file( 1234 );

$csv_file = file( $csv_attachment );

$csv_content = array_map( 'str_getcsv', $csv_file );

Last updated: May 18, 2021